RunLoop使用示例
1.将定时器添加到NSRunLoopCommonModes中,避免在UITrackingRunLoopMode无法执行
滑动ScrollView后系统把RunLoop切换为UITrackingRunLoopMode,因此加载默认模式中的定时器并不会执行,只有滚动停止回到默认模式才会继续执行。我们可以把定时器设为 NSRunLoopCommonModes
的模式,并添加到 run loop 中;
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
2. 在NSDefaultRunLoopMode中加载图片,避免加载图片导致tableView滑动卡顿
当tableview的cell从网络异步加载图片, 加载完成后在主线程刷新显示图片, 这时滑动tableview会造成卡顿. 通常的思路是tableview滑动的时候延迟加载图片, 等停止滑动时再显示图片. 这里我们可以通过RunLoop来实现.
[self.cellImageView performSelector:@sector(setImage:) withObject:downloadedImage afterDelay:0 inModes:@[NSDefaultRunLoopMode]];
3. AFNetworking类似 创建一个常驻的服务线程
+ (void)_networkThreadMain:(id)object {
@autoreleasepool {
[[NSThread currentThread] setName:@"我自己的线程"];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
[runLoop run];
}
}
+ (NSThread *)networkThread {
static NSThread *thread = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
thread = [[NSThread alloc] initWithTarget:self selector:@selector(_networkThreadMain:) object:nil];
if ([thread respondsToSelector:@selector(setQualityOfService:)]) {
thread.qualityOfService = NSQualityOfServiceBackground;
}
[thread start];
});
return thread;
}
在其他地方 通过
[self performSelector:@selector(testApp) onThread:[RunLoopManager networkThread] withObject:nil waitUntilDone:NO];
4. 让Crash的App回光返照
接到crash的Signal后 手动重启RunLoop
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
NSArray *allModes = CFBridgingRelease(CFRunLoopCopyAllModes(runLoop));
while (1) {
for (NSString *mode in allModes) {
CFRunLoopRunInMode((CFStringRef)mode, 0.001, false);
}
}