iOS perfromSelector 和线程的关系
2022-04-12 本文已影响0人
Edviin_2de8
perfromSelector:withObject: afterDelay:
![](https://img.haomeiwen.com/i15934529/2344a92ae58e5623.png)
问题
为什么不打印3
- queue是个串行队列,async异步任务,会开辟一条新线程
- 子线程默认不开启runloop
-
-(void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay;
其实就是在内部创建了 NSTimer ,然后添加到当前的runloop上面,因为子线程没有开启runloop 所以不会打印 - 全局的并发队列也是在子线程中的
测试1
- (void)test2{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"1");
[[NSRunLoop currentRunLoop] run];
[self performSelector:@selector(test) withObject:nil afterDelay:1];
NSLog(@"3");
NSLog(@"%@",[NSRunLoop currentRunLoop]);
});
}
- (void)test{
NSLog(@"2");
}
结果只会只会打印1 ,3 不会打印2
- (void)test2{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"1");
[self performSelector:@selector(test) withObject:nil afterDelay:5];
[[NSRunLoop currentRunLoop] run];
NSLog(@"3");
NSLog(@"%@",[NSRunLoop currentRunLoop]);
});
}
- (void)test{
NSLog(@"2");
}
结果打印123
- (void)test2{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"1");
[self performSelector:@selector(test) withObject:nil afterDelay:5];
NSLog(@"4");
[[NSRunLoop currentRunLoop] run];
NSLog(@"3");
// NSLog(@"%@",[NSRunLoop currentRunLoop]);
});
}
- (void)test{
NSLog(@"2");
}
会打印1-4-2-4
总结
- loop run 只是尝试开启当前线程的runloop,
但是当前线程如果没有任何事件(source、timer、observer)的话,也并不会开启成功
- performSelector 执行的线程就是当前的线程.
- 没有提交当前的runloop的时候,是不会阻塞的,因为perform这个方法是在当前线程中执行的,所以当我们
提交run的时候,检测到有source事件,也就是timer事件,会在当前线程阻塞去执行timer
,当timer执行完毕之后,继续向下执行
performSelectorOnMainThread
- (void)test3{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"1");
[self performSelectorOnMainThread:@selector(test) withObject:nil waitUntilDone:YES];
NSLog(@"3");
});
}
- (void)test{
NSLog(@"%@",[NSThread currentThread]);
sleep(3);
NSLog(@"2");
}
答案是 1,隔3秒然后打印2,在打印3
-
waitUntilDone:NO
,这个参数只是决定是否阻塞当前线程,如果为YES,就需要等待任务结束后才可以向下执行,如果为NO,则不阻塞。
performSelectorInBackground
- (void)test4{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"1");
[self performSelectorInBackground:@selector(test) withObject:nil];
NSLog(@"3");
});
}
- (void)test{
NSLog(@"%@",[NSThread currentThread]);
sleep(3);
NSLog(@"2");
}
打印结果为132,
- 开辟一条新线程
- 在子线程中执行,互不影响,不阻塞当前线程
performSelector:withObject
- (void)test5{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"1");
[self performSelector:@selector(test) withObject:nil];
NSLog(@"3");
});
}
- (void)test{
NSLog(@"%@",[NSThread currentThread]);
sleep(3);
NSLog(@"2");
}
打印结果为123,
说明 performSelector:withObject 会阻塞当前线程,等方法执行完之后,才可以向下执行,
performSelector方法里面是同步的,如果有异步方法,也不会阻塞当前线程