iOS Developer

iOS 多线程之performSelector、死锁

2020-01-09  本文已影响0人  iOS_小久

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];
[self performSelector:@selector(aaa) withObject:nil afterDelay:1];
[[NSRunLoop currentRunLoop] run];
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");
  });
}
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
上一篇 下一篇

猜你喜欢

热点阅读