iOS的多线程跟其他像c语言创建的线程的概念不太一样。
多线程模型为一个个block组成的queue来实现多线程编程,无须自己创建线程。
在ios系统底层为你创建了线程池,我们编写APP只需关心我们需要完成的任务block和queue
queue由一个个block排队组成,最前面的queue在系统取走去执行block中的代码,后面的block就会接上,一个queue对应一个线程会者几个线程 我们无需关心这个。
1. queue
queue分两种 分别是主队列和其他队列, 其中主队列专门负责UI同步和不能被阻塞(需要监听用户及时响应用户的触控), 任何需要复杂计算 持续时间长的行为都交由其他队列执行。
queue类型:dispatch_queue_t
创建 queue:
dispatch_queue_t otherQueue = dispatch_queue_create("queueName", nil);
获取主队列:
dispatch_get_main_queue();
或者 [NSOperationQueue mainQueue];
2. block
oc中称为代码块 就是其他语言中的匿名函数和函数式编程
基本格式 :^(参数类型 参数1,参数类型 参数2) { 需要执行的代码}
3. 如何把需要执行的任务block放入queue?
通过 diapatch_async( queue, ^{ } ); 异步方式调用
还有一种更简单的来让main queue来执行block的方式
- (void)performSelectorOnMainThread:(SEL)aMethod
withObject:object
waitUntilDone:(BOOL)waitUntilDone;
ps: 如何判断block在哪个queue,没有显示的用dispatch_async函数指定那就看你block所在函数是在哪个queue执行就表示block也在那个queue中。不在main queue的block想执行UI操作需回调main queue来实现.
例子:
根据网络URL下载对应的文件
NSURLRequest *request = [NSURLRequest requestWithURL:
[NSURL URLWithString:@"http://..."]];
NSURLSessionConfiguration * configuration = ...... ;
NSURLSession * session = ...... ;
NSURLSessionDownloadTask *task;
task = [session downloadTaskWithRequest:request
completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
/* 想做一些UI动作 能不能执行? */ @1
}];
下载完成的回调函数completionHandler是不是在main queue中,是的话可以直接写ui代码,不是则要通过函数dispatch_async回调main queue来进行操作。
接上面的例子代码 其中session为:
NSURLSession * session = [NSURLSession sessionWithConfiguration:configuration delegate:nil delegateQueue:[NSOperationQueue mainQueue]];
这样创建session指定了是在main queue中执行下载任务 即completionHandler在main queuqe中 在@1处可以直接执行UI操作
相反
NSURLSession *session =
[NSURLSession sessionWithConfiguration:configuration];
是指派了otherQueue来执行下载任务 所以在 @1 处想执行ui操作需回调main queue
@1处此时代码为:
dispatch_async([NSOperationQueue mainQueue], ^{/* UI操作 */}); 或者
[self performSelectorOnMainThread:@selector(doUIthings)
withObject:nil waitUntilDone: NO];
所以多线程入门 只需理解几个概念就行
queue与block的编程模型
main queue和其他queue的不同(main queue 1. 不能阻塞 2. 专门负责ui)
其他的像创建queue , 把block放入queue等函数都必须清楚。
水平有限 欢迎指正