Runloop和线程
WeChat4031bab5eeb59988f3ae48e143763410.png- 一条线程对应一个runloop对象
- 只能在当前线程操作当前runloop,不能操作其他线程的runloop
- RunLoop 对象在第一次获取 RunLoop 时创建,销毁则是在线程结束的时候
Runloop相关类
- CFRunLoopRef:代表 RunLoop 的对象
- CFRunLoopModeRef:代表 RunLoop 的运行模式
- kCFRunLoopDefaultMode:App的默认运行模式,通常主线程是在这个运行模式下运行
- UITrackingRunLoopMode:跟踪用户交互事件(用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他Mode影响
- UIInitializationRunLoopMode:在刚启动App时第进入的第一个 Mode,启动完成后就不再使用
- GSEventReceiveRunLoopMode:接受系统内部事件,通常用不到
- kCFRunLoopCommonModes:伪模式,不是一种真正的运行模式(后边会用到)
- CFRunLoopSourceRef:就是 RunLoop 模型图中提到的输入源 / 事件源
- CFRunLoopTimerRef:就是 RunLoop 模型图中提到的定时源
- CFRunLoopObserverRef:观察者,能够监听 RunLoop 的状态改变
Runloop的应用
Timer的使用
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
相当于
NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
如果希望在scrollview滑动的时候,timer也能走,就这样
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
如果只在scrollview滑动的时候走,就这样
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
ImageView的延迟使用
通过设置runloop的mode,在scrollview的滑动过程中,tableview的cell中的图片不进行加载,只有滑动结束后再进行图片加载
后台常驻线程(很常用)
- 创建一条子线程,strong持有
- (void) run1
{
// 这里写任务
NSLog(@"----run1-----");
// 添加下边两句代码,就可以开启RunLoop,之后self.thread就变成了常驻线程,可随时添加任务,并交于RunLoop处理
[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
// 测试是否开启了RunLoop,如果开启RunLoop,则来不了这里,因为RunLoop开启了循环。
NSLog(@"未开启RunLoop");
}
- 然后随时添加新任务进线程即可
[self performSelector:@selector(run2) onThread:self.thread withObject:nil waitUntilDone:NO];
监控卡顿
- 可以添加Observer到主线程RunLoop中,通过监听RunLoop状态切换的耗时,以达到监控卡顿的目的
网友评论