NSRunLoop

RunLoop就是跑圈, 保证程序一直在执行. App运行起来之后, 即使你什么都不做, 放在那儿它也不会退出, 而是一直在"跑圈", 这就是RunLoop干的事. 主线程会自动创建一个RunLoop来保证程序一直运行. 但子线程默认不创建NSRunLoop, 所以子线程的任务一旦返回, 线程就over了.

RunLoop在某一时刻只能在一种模式下运行, 更换模式时需要暂停当前的Loop, 然后重启新的Loop. RunLoop主要有下面几个模式:

NSDefalutRunLoopMode    : 默认Mode, 通常主线程在这个模式下运行

UITrackingRunLoopMode  : 滑动ScrollView是会切换到这个模式

NSRunLoopCommonModes: 包括上面两个模式

这边需要特别注意的是, 在滑动ScrollView的情况下, 系统会自动把RunLoop模式切换成UITrackingRunLoopMode来保证ScrollView的流畅性.

[NSTimerscheduledTimerWithTimeInterval:1.f                                target:selfselector:@selector(timerAction:)                                  userInfo:nilreports:YES];


当你在滑动ScrollView的时候上面的timer会失效, 原因是Timer是默认加在NSDefalutRunLoopMode上的, 而滑动ScrollView后系统把RunLoop切换为UITrackingRunLoopMode, 所以timer就不会执行了. 解决方法是把该Timer加到NSRunLoopCommonModes下, 这样即使滑动ScrollView也不会影响timer了.

[[NSRunLoop currentRunLoop]addTimer:timerforMode:NSRunLoopCommonModes];   

另外还有一个trick是当tableview的cell从网络异步加载图片, 加载完成后在主线程刷新显示图片, 这时滑动tableview会造成卡顿. 通常的思路是tableview滑动的时候延迟加载图片, 等停止滑动时再显示图片. 这里可以通过RunLoop来实现.

[self.cellImageView performSelector:@sector(setImage:)                        withObject:downloadedImage                        afterDelay:0inModes:@[NSDefaultRunLoopMode]];

当NSRunLoop为NSDefaultRunLoopMode的时候tableview肯定停止滑动了, why? 因为如果还在滑动中, RunLoop的mode应该是UITrackingRunLoopMode.

[[NSThreadcurrentThread] setName:@"AFNetworking"];NSRunLoop*runLoop = [NSRunLoopcurrentRunLoop];        [runLoop addPort:[NSMachPortport] forMode:NSDefaultRunLoopMode];        [runLoop run];

AFNetworking创建了一个新的子线程(在子线程中调用NSRunLoop *runloop = [NSRunLoop currentRunLoop]; 获取RunLoop对象的时候, 就会创建RunLoop), 然后把它加到RunLoop里面来保证它一直运行.

使用CFRunLoop来启动/停止

[self.connection scheduleInRunLoop:[NSRunLoopcurrentRunLoop]                          forMode:NSRunLoopCommonModes];

CFRunLoopRun();

// CFRunLoopStop()停止





参考: https://www.jianshu.com/p/ebb3e42049fd

你可能感兴趣的:(NSRunLoop)