1,operationQueue 里边应该可以同时添加多个operation吧?
是的,本来operationQueue的目的就是多线程管理,那多线程,可不只是一个线程。
而且我们可以设置这个队列每次被处理的“操作”数量
这里的setMaxConcurrentOperationCount就是同时被处理的“操作数”,参数为整数int或NSInteger (两个是一样的,不记得的可以在我的博客里面搜索一下噢~)
2,那main函数应该怎么写?
main函数中其实只需要写你要在另外一个进程里面作的事情。比如对于我来说,我常常只是作一个简单的事情,那我会用NSInvocationOperation,NSOperation的简化版。比如说:
在doSomeThing函数里面,我可以从网上读取一些东西,但是读取是需要占用时间,而堵塞主线程的。而使用NSOperation这样使用就不会了。
而如果是NSOperation,虽然复杂了一些,又是做一个NSOperation的子类。其实main函数做得事情和doSomeThing是一抹一样的。只不过如果你制作这个子类,你对其操作的内容可以更多,可以制作更复杂的读取,载入操作等等,而且你可以重复使用这个类功能阿。再者,NSOperation也提供了对runtime操作的支持,不过那就太麻烦了,一般不大用的上。
NSOperation
多线程编程是防止主线程堵塞,增加运行效率等等的最佳方法。而原始的多线程方法存在很多的毛病,包括线程锁死等。在Cocoa中,Apple提供了NSOperation这个类,提供了一个优秀的多线程编程方法。
本次讲解NSOperation的使用方法:
1,将想在另外一个线程的工作单独成类,并设置其父类为NSOperation:
2,借由其初始化方法来传入所需要的参数和对象
呼叫这个类对象的时候,传入所需要的参数和对象
3,在我们的线程操作类中的main函数执行所需要的工作
这些就是一个简单的NSOperation的使用过程了。其实看看嘛,非常简单的,正如苹果为我们准备的其他API一样!
本次介绍NSOperation的子集,简易方法的NSInvocationOperation:
一个NSOperationQueue 操作队列,就相当于一个线程管理器,而非一个线程。因为你可以设置这个线程管理器内可以并行运行的的线程数量等等。下面是建立并初始化一个操作队列:
简单介绍之后,其实可以发现这种方法是非常简单的。很多的时候我们使用多线程仅仅是为了防止主线程堵塞,而NSInvocationOperation就是最简单的多线程编程,在iPhone编程中是经常被用到的。
下面是一个单例顺序执行的例子:
- (IBAction)touchUpInsideByThreadOne:(id)sender {
NSInvocationOperation *invoOpe = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(didRunOperation:) object:[NSNumber numberWithInt:10]];
NSInvocationOperation *invoOpe2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(didRunOperation:) object:[NSNumber numberWithInt:5]];
NSInvocationOperation *invoOpe3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(didRunOperation:) object:[NSNumber numberWithInt:1]];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:1];
[queue addOperation:invoOpe];
[queue addOperation:invoOpe2];
[queue addOperation:invoOpe3];
[invoOpe2 setCompletionBlock:^{
NSLog(@"invoOpe2 complete.");
}];
}
- (void)didRunOperation:(NSNumber *)num
{
sleep(num.intValue);
NSLog(@"run with wait time:%d", num.intValue);
}
输出结果为:可以看到是顺序执行的,不管第一个需要运行多长时间
2013-07-24 15:19:18.356 NSThreadDemo[1392:12b03] run with wait time:10
2013-07-24 15:19:23.360 NSThreadDemo[1392:12307] run with wait time:5
2013-07-24 15:19:23.361 NSThreadDemo[1392:12b07] invoOpe2 complete.
2013-07-24 15:19:24.362 NSThreadDemo[1392:12307] run with wait time:1
但是将[invoOpe2 setCompletionBlock:^{稍微改一改,会发现,invoOpe2的CompletionBlock还没有执行完,就执行invoOpe3了,有什么办法去处理这个问题呢?
[invoOpe2 setCompletionBlock:^{
sleep(3);
NSLog(@"invoOpe2 complete.");
}];
运行的结果为:
2013-07-24 15:40:14.282 NSThreadDemo[1485:12303] run with wait time:10
2013-07-24 15:40:19.286 NSThreadDemo[1485:12303] run with wait time:5
2013-07-24 15:40:20.290 NSThreadDemo[1485:12e0b] run with wait time:1
2013-07-24 15:40:22.288 NSThreadDemo[1485:1500f] invoOpe2 complete.
办法当然有,如果将上面的
[invoOpe2 setCompletionBlock:^{之前加上[invoOpe3 addDependency:invoOpe2];就可以保证在invoOpe2的CompletionBlock执行完成后才执行invoOpe3了,修改如下:
[invoOpe3 addDependency:invoOpe2];
[invoOpe2 setCompletionBlock:^{
sleep(3);
NSLog(@"invoOpe2 complete.");
}];
结果为:
2013-07-24 15:42:33.920 NSThreadDemo[1513:12303] run with wait time:10
2013-07-24 15:42:38.924 NSThreadDemo[1513:14f0b] run with wait time:5
2013-07-24 15:42:41.926 NSThreadDemo[1513:12b0b] invoOpe2 complete.
2013-07-24 15:42:42.928 NSThreadDemo[1513:12507] run with wait time:1