iOS 多线程之performSelector、死锁
1. performSelector
//在当前线程推迟1s执行,响应了OC语言的动态性:推迟到运行时才绑定方法[self performSelector:@selector(aaa) withObject:nil afterDelay:1];// 回到主线程,waitUntilDone:能否将该回调方法执行完再执行后面的代码// 假如为YES:就必需等回调方法执行完成之后才能执行后面的代码,说白了就是阻塞当前的线程// 假如是NO:就是不等回调方法结束,不会阻塞当前线程[self performSelectorOnMainThread:@selector(aaa) withObject:nil waitUntilDone:YES];// 开拓子线程[self performSelectorInBackground:@selector(aaa) withObject:nil];//在指定线程执行[self performSelector:@selector(aaa) onThread:[NSThread currentThread] withObject:nil waitUntilDone:YES];
- 需要注意的是:假如是带
afterDelay
的延时函数,会在内部创立一个NSTimer
,而后增加到当前线程的Runloop
中。也就是假如当前线程没有开启runloop
,该方法会失效。在子线程中,需要启动runloop
(注意调用顺序)
[self performSelector:@selector(aaa) withObject:nil afterDelay:1];[[NSRunLoop currentRunLoop] run];
performSelector:withObject:
只是一个单纯的消息发送,和时间没有一点关系。所以不需要增加到子线程的Runloop
中也能执行- 下面代码片段的test方法会去执行吗?
dispatch_async(dispatch_get_global_queue(0, 0), ^{ [self performSelector:@selector(test:) withObject:nil afterDelay:0];});
这里的test方法是不会去执行的,起因在于- (void)performSelector: withObject: afterDelay:
这个方法要创立提交任务到runloop
上的,而gcd
底层创立的线程是默认没有开启对应runloop
的,所有这个方法就会失效。
而假如将dispatch_get_global_queue
改成主队列,因为主队列所在的主线程是默认开启了runloop
的,就会去执行(将dispatch_async
改成同步,由于同步是在当前线程执行,那么假如当前线程是主线程,test
方法也是会去执行的)
2. 死锁
- 死锁就是队列引起的循环等待,一个比较常见的死锁例子:主队列同步
- (void)viewDidLoad { [super viewDidLoad]; dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"deallock"); });}
在主线程中运用主队列同步,也就是把任务放到了主线程的队列中。同步对于任务是立刻执行的,那么当把任务放进主队列时,它就会立马执行,只有执行完这个任务,
viewDidLoad
才会继续向下执行。而viewDidLoad
和任务都是在主队列上的,因为队列的先进先出准则,任务又需等待viewDidLoad
执行完毕后才能继续执行,viewDidLoad
和这个任务就形成了相互循环等待,就造成了死锁。
想避免这种死锁,可以将同步改成异步dispatch_async
或者者将dispatch_get_main_queue
换成其余串行或者并行队列,都可以处理同样,下边的代码也会造成死锁:
dispatch_queue_t serialQueue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);dispatch_async(serialQueue, ^{ dispatch_sync(serialQueue, ^{ NSLog(@"deadlock"); });});
外面的函数无论是同步还是异步都会造成死锁。这是由于里面的任务和外面的任务都在同一个serialQueue
队列内,又是同步,这就和上边主队列同步的例子一样造成了死锁。
处理方法也和上边一样,将里面的同步改成异步dispatch_async
或者者将serialQueue
换成其余串行或者并行队列,都可以处理
另外,假如你想一起进阶,不妨增加一下交流群1012951431,选择加入一起交流,一起学习。期待你的加入!
02.png
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » iOS 多线程之performSelector、死锁