杨小麦OC之旅--RunLoop&&NSTimer
Posted Jolie_Yang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了杨小麦OC之旅--RunLoop&&NSTimer相关的知识,希望对你有一定的参考价值。
6th,Dec,2015
RunLoop 运行在某个线程中的死循环,从事件队列中取出一个事件分派给监听器。多任务最基本的形式是运行循环。 “应用程序由一个处于阻塞状态的 do/while循环驱动,当有事件发生时,分派给合适的监听器,如此反复直到循环停止。处理分派的对象就叫做NSRunLoop.” App运行后能接收到用户事件并执行相应操作,操作完成后然后等待用户事件,直到app退出。 线程在执行中的休眠和激活就是由RunLoop对象进行管理的。主线程的运行循环是默认开启的
Cocoa NSRunLoop // 线程不安全 Core Foundation CFRunLoopRef // 线程安全
NSRunLoop 使用: 1.定时器未开启,需手动开启。 比如:NSTimer不用scheduled方式初始化的定时器,需要手动addTimer将timer添加到一个runloop中。
2.某些延迟函数和选择器在分线程中的使用,我们必须手动开启RunLoop
// 获取当前循环 // 获取主线程循环
// 将定时器添加到RunLoop当中。
// 获取下个响应时间
- (NSDate *)limitDateForMode:(NSString *)mode;
如果错过了某个时间点,定时器并不会延时调用,而是直接等待下一个时间点调用,所以定时器并不是精准的定时器 NSTimer基于运行循环进行消息分派 定时器的执行: 不是按照时间间隔进行调用,而是在定时器注册到RunLoop后,设置一个时间点进行调用。错过则不会延迟调用。 // 初始化方法
注: scheduled的初始化方法将以 默认mode(NSDefaultRunLoopMode)直接添加到当前的runloop中. 特殊情况:scheduled方法不会执行。 1.当前线程的RunLoop为UI线程时,Mode就切换成其他Mode(NSEventTrackingRunLoopMode),所以默认mode中注册的事件就不会别执行。 2. 在scroll一个页面时来松开,此时connection不会收到消息,由于scroll时runloop为UITrackingRunLoopModes模式,不接收输入源,此时要修改connection的mode 不被UI干扰的Timer:使用NSRunLoop的addTimer:forMode:方法来把Timer按照指定模式加入到Run Loop中。这里使用的模式是: NSRunLoopCommonModes,这个模式等效于NSDefaultRunLoopMode和NSEventTrackingRunLoopMode的结合。
RunLoopMode
一个集合,包括监听:事件源,定时器,以及需通知的runloop observers
模式包括:
Default模式:几乎包括所有输入源(除NSConnection) NSDefaultRunLoopMode模式
Connection模式:处理NSConnection事件,属于系统内部,用户基本不用
Modal模式:处理modal panels
Event tracking模式:如组件拖动输入源 UITrackingRunLoopModes 不处理定时事件
Common modes模式:NSRunLoopCommonModes 这是一组可配置的通用模式。将input sources与该模式关联则同时也将input sources与该组中的其它模式进行了关联。
// 声明
// 移除 invalidate是唯一的办法将定时器从RunLoop中注销从循环池中移除的方法。
在某个界面释放前,将这个定时器停止,甚至置为nil,都不能真正释放,原因是系统的循环池中还保有这个对象。
参考资料: 《ios编程实战》第9章
iOS中RunLoop机制浅探
RunLoop机制理解
IOS NSTimer 定时器用法总结
iOS:.NSRunLoop再理解
以上是关于杨小麦OC之旅--RunLoop&&NSTimer的主要内容,如果未能解决你的问题,请参考以下文章