半夜逛微博发现有人说NSRunLoop可以用来阻塞线程,最近对多线程比较敏感搜索下NSRunLoop先
大部分文章是以这个例子开讲
- (IBAction)start:(id)sender{
① pageStillLoading = YES;
② [NSThread detachNewThreadSelector:@selector(loadPageInBackground:)toTarget:self withObject:nil];
③ [progress setHidden:NO];
while (pageStillLoading) {
④ NSLog(@"123");
⑤ [NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
⑥[progress setHidden:YES];
}
用来实现当子线程方法loadPageInBackground运行完毕之后再往下运行⑥,这样的话那为什么不把loadPageInBackground直接用主线程执行?难道⑤阻塞的不是主线程?切换到mac试试先
试了下 这样写确实不会阻塞主线程 但虽然在loadPageInBackground方法中设置了pageStillLoading=NO , 但⑥并不会马上执行,而且是很久时间或者是屏幕接收到新的事件才执行
可能⑤为pageStillLoading增加了一个类似于kvo的观察者, 因为④在⑥执行前只执行了一次,特别地当屏幕接收到新事件时,④会突然执行多次…… 有点意思 深入了解下NSRunLoop先
看了几个帖子,有些讲的太深入暂时没理解透彻,http://blog.csdn.net/lengshengren/article/details/12905627 不过这篇文章解决了之前的疑问,里面说道:
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate: [NSDate distantFuture]]; //主线程等待,但让出主线程时间片;有事件到达就返回,比如点击UI等。
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate: [NSDate dateWithTimeIntervalSinceNow:10.0]]; //主线程等待,但让出主线程时间片;有事件到达就返回,如果没有则过10秒返回。
大部分文章是以这个例子开讲
- (IBAction)start:(id)sender{
① pageStillLoading = YES;
② [NSThread detachNewThreadSelector:@selector(loadPageInBackground:)toTarget:self withObject:nil];
③ [progress setHidden:NO];
while (pageStillLoading) {
④ NSLog(@"123");
⑤ [NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
⑥[progress setHidden:YES];
}
用来实现当子线程方法loadPageInBackground运行完毕之后再往下运行⑥,这样的话那为什么不把loadPageInBackground直接用主线程执行?难道⑤阻塞的不是主线程?切换到mac试试先
试了下 这样写确实不会阻塞主线程 但虽然在loadPageInBackground方法中设置了pageStillLoading=NO , 但⑥并不会马上执行,而且是很久时间或者是屏幕接收到新的事件才执行
可能⑤为pageStillLoading增加了一个类似于kvo的观察者, 因为④在⑥执行前只执行了一次,特别地当屏幕接收到新事件时,④会突然执行多次…… 有点意思 深入了解下NSRunLoop先
看了几个帖子,有些讲的太深入暂时没理解透彻,http://blog.csdn.net/lengshengren/article/details/12905627 不过这篇文章解决了之前的疑问,里面说道:
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate: [NSDate distantFuture]]; //主线程等待,但让出主线程时间片;有事件到达就返回,比如点击UI等。
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate: [NSDate dateWithTimeIntervalSinceNow:10.0]]; //主线程等待,但让出主线程时间片;有事件到达就返回,如果没有则过10秒返回。
其实之前⑤中的currentRunLoop就是这里的mainRunLoop,只要mainRunLoop没有接收到新事件,⑤就不会返回,解释了为什么“虽然在loadPageInBackground方法中设置了pageStillLoading=NO , 但⑥并不会马上执行,而且是很久时间或者是屏幕接收到新的事件才执行” 其实是让mainRunLoop有机会去接收其它事件,那为什么不直接这样写
while (pageStillLoading) {
NSLog(@"123");
sleep(1);
}
因为这种方式是很消耗CPU时间片的,而改用NSRunLoop来实现,可以大大改善线程执行效率,而且不会阻塞主线程。