Blocks可以简化并发任务
一个block就相当于一个独特的工作单元,将可执行的代码和周围范围内捕捉的可选状态结合。这使得它非常适合用于iOS和OS X异步调用的并发选项之一。而不是必须弄清楚像线程一样的各个低级机制,你可以简单的通过使用blocks来定义你的任务,同时,让系统像加工资源一样的去执行这些任务变得更加可行。
OS X和iOS提供都为并发提供一种多样化的技术,包括两个任务调度机制:Operation queues 和 Grand Central Dispatch (操作队列和中央调度),这些机制围绕着等待被调用的任务队列去考虑。如果你需要调用它们的话,你可以在你的队列中增加你的blocks,并且,当处理器的时间和资源变得可用的时候,系统为了进行调用将它们排好队。
一组连续的队列只需要允许一个任务在一个时间内被执行-下一个队列中的任务将不会被排队和调用直到前一个任务完成为止。一个并发的队列调用次数和它可以做的任务数量一样多,不需要等到前一个任务完成。
使用操作队列的block操作
一个操作队列是Cocoa 和CocoaTouch的任务调度方法。你创造了一个NSOperation实例来封装当前的工作单元和任何必要的数据,然后将操作添加到一个NSOperationQkeue中去执行。
尽管你可以创造你自定义的NSOperation子类去执行复杂的任务,同样通过使用一个bloc使用NSBlockOperation去创造一个操作也是能够的,像下面这样:
NSBlockOperation *operation = [NSBlock Operation blockOperationWithBlock :^ {
...
}];
可以手动执行操作,但是通常会将操作添加到现有的队列或你自己一个创建的队列中以便执行:
//schedule task on main queue:
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
[mainQueue addOperation:operation];
//schedule task on background queue:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperaion:operation];
如果你使用一个操作队列,你可以配置这些操作之间的优先级或者依赖,例如一个队列不能够被执行直到一组其他的操作执行完成。你同样可以监视你的操作执行的状态变化通过键-值观察,从而是的升级一个进度指示变得更简单,就像一个任务的完成一样。
带有Grand Central Dispatch的Dispatch Queues的调度Blocks
如果你想要安排任意代码块执行,你可以直接使用由Grand Central Dispatch 控制的dispatch queues。Dispatch queues可以使得不管是异步还是同步执行任务都变得简单花,通过合理的调用和根据先进先出顺序执行它们的任务。
同样的你也可以创建你自己的diaspatch queues或者可以使用GCD提供的自动队列。如果你需要去调度一个并发执行的任务,比如说,你可以参考通过使用dispatch_get_global_queue()方法和具体设置一个队列的优先级来获得一个存在的队列,像下面这样:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
将block发送到队列,你可以使用dispatch_async()或者dispatch_sync()方法。这个dispatch_async()方法直接返回而不需要等待其他block被调用:
dispatch_async(queue,^{
NSLog(@"Block for asynchronous execution");
});
这个dispatch_sync()方法不会返回直到block被执行完;你可以在一个并发block在继续执行前需要去等待另一个任务在主线程中完成这样的一个场景下使用它。