从接触iOS到如今也有将近两年了,对iOS中的RunLoop也有了必定的认识,下面讲讲我的对RunLoop的理解。html
初识RunLoop程序员
RunLoops是与线程相关联的基础部分,一个Run Loop就是事件处理循环,他是用来调度和协调接收到的事件处理。使用RunLoop的目的,就是使的线程有工做须要作的时候忙碌起来,当没事作的时候,又可使得线程休眠。swift
咱们通常程序就是执行一个线程,是一条直线.有起点终点.而runloop就是一直在线程上面画圆圈,一直在跑圈,除非切断不然一直在运行。网上说的比喻很好,直线就像昙花一现同样,圆就像OS,一直运行直到你关机为止。网络
RunLoop资料app
苹果官方文档:框架
CFRunLoopRef是开源的:动画
http://opensource.apple.com/source/CF/CF-1151.16/spa
iOS中有两套API来访问和使用RunLoop线程
NSRunLoop和CFRunLoopRef都表明着RunLoop对象
NSRunLoop是基于CFRunLoopRef的一层OC包装, 因此要了解RunLoop内部结构, 须要多研究CFRunLoopRef层面的API(Core Foundation层面)
[NSRunLoop currentRunLoop]; // 得到当前线程的RunLoop对象 [NSRunLoop mainRunLoop]; // 得到主线程的RunLoop对象
CFRunLoopGetCurrent(); // 得到当前线程的RunLoop对象 CFRunLoopGetMain(); // 得到主线程的RunLoop对象
若是在主线程中: 当前线程的RunLoop对象和主线程的RunLoop对象取得的是相同的。
CFRunLoopSourceRef
RunLoop
包含若干个Mode
,每一个Mode
又包含若干个Source
/Timer
/Observer
[NSRunLoop currentRunLoop].currentMode
)Source
/Timer
/Observer
,让其互不影响(切换模式是为了,让它按照另外一个模式的Source,Timer,Observer来跑圈, 互不影响)RunLoop 启动必需要传入一个模式,RunLoop有多个模式, 可是每次只能运行一种模式
RunLoop定义两个Version的Source
向内部报告RunLoop当前状态的更改 CAAnimation
能够监听的时间点以下几点:
UIKit经过RunLoopObserver在RunLoop两次Sleep间对AutoreleasePool进行pop和push,将此次Loop中产生的Autorelease对象释放。(好像swift中没有关于释放的问题)
CFRunLoopModeRef
RunLoop在同一时段只能且必须在一种特定Mode下Run 更换Mode时, 须要暂停当前的Loop,而后重启新的Loop NSDefalutRunLoopMode 默认状态.空闲状态 UITrackingRunLoopMode 滑动ScrollView UIInitializationRunLoopMode 私有,App启动时 NSRunLoopCommonModes 默认包括上面第一和第二
/** * 这个方法内部实现是: 建立timer,添加到RunLoop中的默认的Mode中,RunLoop启动这个mode,取出这个mode中timer来用 */ [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(run) userInfo:nil repeats:YES]; /** * 上面的代码等同于下面的 */ // 建立Timer NSTimer *timer = [NSTimer timerWithTimeInterval:0.5 target:self selector:@selector(run) userInfo:nil repeats:YES]; // 定时器只运行在 NSDefaultRunLoopMode 模式下, 一旦RunLoop进入其余模式,这个定时器就不会工做 [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; // 若是拖动时, 咱们将定时器添打上这个NSRunLoopCommonModes的标记 [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; NSLog(@"-----------%@", [NSRunLoop currentRunLoop]); /** * 定时器会跑在标记为common modes的模式下(这个模式只是个标记) * RunLoop会寻找带有common标签的模式,有这个标签的,均可以跑 * 打印当前的RunLoop信息输出为:(有common modes标签的有两个,UITrackingRunLoopMode和kCFRunLoopDefaultMode),因此定时器能够在这两个模式下跑, RunLoop只会运行一种模式 common modes = <CFBasicHash 0x7fb8b2700490 [0x10ec6ba40]>{type = mutable set, count = 2, entries => 0 : <CFString 0x10fba2210 [0x10ec6ba40]>{contents = "UITrackingRunLoopMode"} 2 : <CFString 0x10ec8c5e0 [0x10ec6ba40]>{contents = "kCFRunLoopDefaultMode"} } */
AFNetWorking 中建立RunLoop
[[NSThread currentThread] setName:@"AFNetworking"]; NSRunLoop *runloop = [NSRunLoop currentRunLoop]; [runLoop addPort:[NSMachPort port] forMode:NSDefalutRunLoopMode]//一直活着 [runLoop run];
这在处理网络响应是一个很好的方法
UITrackingRunLoopMode 与 NSTimer
// 默认状况下NSTimer被加入NSDefalutRunLoopMode //若是想NSTimer受到组件或者动画影响 添加到NSRunLoopCommonModes [[NSRunLoop currentRunLoop]addTimer:timer...forMode:NSRunLoopCommonModes];
RunLoop的处理逻辑是什么呢?
每次运行run loop,你线程的run loop对会自动处理以前未处理的消息,并通知相关的观察者。具体的顺序以下:
好的文章都是值得反复看的,咱们在不一样的阶段来相同的文章或资料都能有不一样的收获, 提升本身对知识的理解,声明一下:最好是本身理解后再总结一次,不要一味的收藏, 每一个程序员都有着成为大牛的潜质,只在是否努力。加油 技术宅们!