我个人非常喜欢用GCD,但是某些情况下一般会使用NSOperationQueue。
1、取消某个操作。
如果使用NSOperation,那么想要取消操作,只要任务运行之前,在NSOperation对象上调用cancel方法,但是无法取消已运行的任务。而GCD队列是无法取消的。
2、指定操作的优先级。
操作优先级表示操作与队列中其他操作之间的优先关系。优先级高的操作先执行,优先级低的后执行。GCD只有针对整个队列的优先级,没有针对每个block的优先级,需要自己编写调度算法,而NSOperationQueue所提供的功能要比GCD更为便利。NSOperation对象也有“线程优先级”,这决定了运行此操作的线程处在何种优先级上。用GCD也可以实现此功能,然而采用操作队列更简单,只需设置一个属性。
3、通过KVO监控NSOperation对象的属性。
NSOperation对象有许多属性都适合通过KVO来监听,比如可以通过isCancelled属性来判断任务是否已取消,又比如可以通过isFinished属性来判断任务是否已完成。如果想在某个任务变更其状态时得到通知,或是想用比GCD更为精细的方式来控制所要执行的任务,那么KVO机制会很有用。
4、重用NSOperation对象。
系统内设置了一些NSOperation的子类,比如NSBlockOperation,供开发者调用,我们也可以自己来创建。这些类就是普通的Objective-C对象,能够存放任何信息。对象在执行时可以充分利用存于其中的信息,而且还可以随意调用定义在类中的方法。这就比GCD中的那些简单的Block块要强大许多。这些NSOperation类可以在代码中多次使用,它们符合软件开发中的“不重复”原则。
5、指定操作间的依赖关系。
一个操作可能依赖其他多个操作。开发者能够指定操作之间的依赖关系,使特定的操作必须在另外一个操作顺利执行完毕之后方可执行。比如,从服务器端下载并处理文件的动作,可以用操作来表示,而在处理其他文件之前,必须先下载“清单文件”。后续的下载操作,都要依赖于下下载清单文件这一操作。如果操作队列允许并发的话,那么后续的多个下载操作就可以同时进行,但前提是它们所依赖的那个清单文件下载操作已经执行完毕。