Quantcast
Channel: IT社区推荐资讯 - ITIndex.net
Viewing all articles
Browse latest Browse all 11807

浅谈 iOS 线程

$
0
0
  • 通常主线程和其他线程的使用场景
    主线程一般用于
    绘制UI
    响应用户操作等
    其他线程用于
    网络请求
    解析网络返回等

    Tips: 解压、打开 Zip 包,读写较大文件的操作也不宜放在主线程里。

一般异步网络请求中会有一个 completionBlock ,这个 completionBlock 是在主线程中被调用的。
所以,可能消耗大量时间的代码(例如上面提到的处理 Zip 包的方法)也不宜放在这些 block 中。如下面的代码所示:

[request setCompletionBlock:^{
    NSLog(@"Zip file downloaded.");
    NSData *data = [request responseData];
    [self processZip:data sourceURL:sourceURL]; // Ack - heavy work on main thread!
}];

那么,如果在blcok 中有数据需要花费大量时间处理,我们可以使用 Grand Central Dispatch(GCD)系统,让数据在后台被处理,或者使用GCD在后台执行这些代码。简单来说,如果希望有代码在后台执行,只需要调用 dispatch_async,然后把代码扔进去。
接来下的事就交给 GCD 啦,如果需要,GCD 会创建一个新的线程;或者 GCD 会重用一个已经存在的可用线程。

当你调用 dispatch_async 的时候,就是将代码传入了一个 dispatch 队列,这个队列里存储了所有你传入的 block。

我们可以创建自己的 dispatch 队列(通过 dispatch _create 方法),也可以为了主线程的到一个特殊的队列(通过 dispatch_get_main_queue)。

一个 dispatch 队列(queue)是按次序排设好的,这就意味着队列中每次只有一个 block 的代码被执行。这个特性非常方便,我们可以用它保护共享数据(shared data)。
关于保护数据的核心思想是:你需要设置好你的代码,使得一个特定的数据结构只能被一个特定的正在运行的 dispatch 队列所访问。因为 dispatch 队列按次序执行 block,那么每次就只有一个block 能够访问该数据结构。

  • GCD 实践

预先声明一个dispatch_queue,添加一个 dispatch queue 实例

// Add new instance variable
dispatch_queue_t backgroundQueue;

关于 dispatch_queue_t 苹果官方文档说明:一个 dispatch queue 是一个用来注册将要被按顺序执行的代码块的轻量级对象。

创建dispatch queue
backgroundQueue = dispatch_queue_create("com.razeware.imagegrabber.bgqueue", NULL);
初始化前面说声明的 dispatch queue,并给这个dispatch queue 命名。上面填 null 参数的地方还可以填 DISPATCH_QUEUE_SERIAL(等同于null)或者 DISPATCH_QUEUE_CONCURRENT。
DISPATCH_QUEUE_SERIAL :按先进先出原则执行 block 的 dispatch 队列。
DISPATCH_QUEUE_CONCURRENT:执行当前 block 的 dispatch 队列。虽然该队列执行的是当前的代码,我们也可以使用 barrier block 在队列中创建同步点。

使用刚才创建的 dispatch queue

- (void)process {   
    dispatch_async(backgroundQueue, ^(void) {
        [self processHtml];
    });   
}

原本 - (void)process 中的代码是直接执行 [self processHtml]; processHTMl 方法阻塞了主线程,而现在通过调用 dispatch_async 我们可以使得 processHtml 在我们创建的 backgroundQueue 中在后台运行。

  • 关于NSOperations 和 operation 序列

NSOperations 其实就是基于 GCD 实现的,使用NSOperation 的时候其实也就是在使用 GCD。但是NSOperation 给我们提供了更多更方便的功能,我们可以操作一些 operation,这些operation 依赖于其他 operation。还可以在 submit block 之后重新对 operation queue 进行排序。

Bingo!
之后应该会总结一些关于 GCD 使用的更详细的文章。


Viewing all articles
Browse latest Browse all 11807

Trending Articles