在iOS开发中,谈到多线程,大家第一时间想到的一定是GCD。GCD固然是一套强大的多线程解决方案,能够解决绝大多数的多线程问题,但是他易于上手难于精通且到处是坑的特点也注定了想熟练使用它有一定的难度。而且很多人嘴上天天挂着GCD,实际上对它的实际应用也不甚了解。
再者说,在现在的主流开发模式下,能用到多线程的绝大多数就是网络数据请求和网络图片加载,这两点上AFNetwork+SDWebImage已经能满足几乎所有的需求。而剩下的一小部分,简单好用的NSOperation无疑是比GCD更有优势的。
因此,如果你还是坚持『GCD大法好』,那看到这里就不必再看了。如果你想试一试更简单的方法,那就随我来吧。
什么是NSOperation?
和GCD一样,NSOperation也是苹果提供给我们的一套多线程解决方案。实际上它也是基于GCD开发的,但是比GCD拥有更强的可控性和代码可读性。
NSOperation是一个抽象基类,基本没有什么实际使用价值。我们使用最多的是系统封装好的NSInvocationOperation
和NSBlockOperation
。
不过NSOperation一些通用的方法你要知道
1 2 3 4 5 6 7 8 9 |
NSOperation * operation = [[NSOperation alloc]init]; //开始执行 [operation start]; //取消执行 [operation cancel]; //执行结束后调用的Block [operation setCompletionBlock:^{ NSLog(@"执行结束"); }]; |
使用NSInvocationOperation
NSInvocationOperation的使用方式和给Button添加事件比较相似,需要一个对象和一个Selector。使用方法非常简单。
我们先来写一个方法
1 2 3 4 |
- (void)testNSOperation { NSLog(@"我在第%@个线程",[NSThread currentThread]); } |
然后调用它
1 2 3 4 |
//创建 NSInvocationOperation * invo = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(testNSInvocationOperation) object:nil]; //执行 [invo start]; |
得到这样的执行结果
我们可以看到NSInvocationOperation其实是同步执行的,因此单独使用的话,这个东西也没有什么卵用,它需要配合我们后面介绍的NSOperationQueue去使用才能实现多线程调用,所以这里我们只需要记住有这么一个东西就行了。
使用NSBlockOperation
- 终于到了我们今天的第一个重点
NSBlockOperation也是NSOperation的子类,支持并发的实行一个或多个block,使用起来简单又方便
执行以下代码
12345678910111213141516171819NSBlockOperation * blockOperation = [[NSBlockOperationblockOperationWithBlock:^{NSLog(@"1在第%@个线程",[NSThread currentThread]);}];[blockOperation addExecutionBlock:^{NSLog(@"2在第%@个线程",[NSThread currentThread]);}];[blockOperation addExecutionBlock:^{NSLog(@"3在第%@个线程",[NSThread currentThread]);}];[blockOperation addExecutionBlock:^{NSLog(@"4在第%@个线程",[NSThread currentThread]);}];[blockOperation addExecutionBlock:^{NSLog(@"5在第%@个线程",[NSThread currentThread]);}];[blockOperation addExecutionBlock:^{NSLog(@"6在第%@个线程",[NSThread currentThread]);}];
这里我们多执行两次并比较结果
- 通过三次不同结果的比较,我们可以看到,NSBlockOperation确实实现了多线程。但是我们可以看到,它并非是将所有的block都放到放到了子线程中。通过上面的打印记录我们可以发现,它会优先将block放到主线程中执行,若主线程已有待执行的代码,就开辟新的线程,但最大并发数为4(包括主线程在内)。如果block数量大于了4,那么剩下的Block就会等待某个线程空闲下来之后被分配到该线程,且依然是优先分配到主线程。
- 另外,同一个block中的代码是同步执行的
为了证明以上猜想,我们为它增加更多block,并给每条block添加两行代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
着GCD,实际上对它的实际应用也不甚了解。
再者说,在现在的主流开发模式下,能用到多线程的绝大多数就是网络数据请求和网络图片加载,这两点上AFNetwork+SDWebImage已经能满足几乎所有的需求。而剩下的一小部分,简单好用的NSOperation无疑是比GCD更有优势的。 因此,如果你还是坚持『GCD大法好』,那看到这里就不必再看了。如果你想试一试更简单的方法,那就随我来吧。 什么是NSOperation?和GCD一样,NSOperation也是苹果提供给我们的一套多线程解决方案。实际上它也是基于GCD开发的,但是比GCD拥有更强的可控性和代码可读性。 NSOperation是一个抽象基类,基本没有什么实际使用价值。我们使用最多的是系统封装好的 不过NSOperation一些通用的方法你要知道
使用NSInvocationOperationNSInvocationOperation的使用方式和给Button添加事件比较相似,需要一个对象和一个Selector。使用方法非常简单。
然后调用它
得到这样的执行结果 执行结果
我们可以看到NSInvocationOperation其实是同步执行的,因此单独使用的话,这个东西也没有什么卵用,它需要配合我们后面介绍的NSOperationQueue去使用才能实现多线程调用,所以这里我们只需要记住有这么一个东西就行了。 使用NSBlockOperation
第一次执行的结果
第二次执行的结果
第三次执行的结果
为了证明以上猜想,我们为它增加更多block,并给每条block添加两行代码。
然后调用它 |