IOS的RunLoop。

一、关于RunLoop

程序启动后会加载一个固定的RunLoop,用以使程序可以一直存活。如果没有RunLoop,程序一启动就被退出了。
RunLoop除了使程序存活,还有的作用就是在程序不在工作的时候,要通知CPU空出来做其他的事情,并等待用户再次进入应用的时候能马上进入工作。

Runloop有五种状态:

1.kCFRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode下运行2.UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响

3.UIInitializationRunLoopMode:在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用,会切换到kCFRunLoopDefaultMode

4.GSEventReceiveRunLoopMode:接受系统事件的内部 Mode,通常用不到5.kCFRunLoopCommonModes:这是一个伪Mode,作为标记kCFRunLoopDefaultMode和UITrackingRunLoopMode用,并不是一种真正的Mode

处理定时器的问题

RunLoop最常用的地方是处理NSTimer在ScrollView滚动的时候回停止运行,滚动结束会继续运行。
NSTimer默认添加在默认(kCFRunLoopDefaultMode)状态,在ScrollView滚动的时候RunLoop会被切换到追踪(UITrackingRunLoopMode)状态,所以造成NSTimer的暂停。
解决方法:
1.两种状态都加上NSTimer,但这不是最优解,这样会有2个timer,不是同一个。
2.NSTimer添加的时候选择通用(kCFRunLoopCommonModes),可以理解为,添加为kCFRunLoopCommonModes后,不管是切换到哪一个都是会被执行的,也就不会存在被暂停的问题了。

关于自动释放池(NSAutoreleasePool)的问题


苹果在解释RunLoop的时候,举例了自动释放池。
APP启动后,在RunLoop注册了2个observer,回调在_wrapRunLoopWithAutoreleasePoolHandler()。第一个就是在Entry(即将进入)创建了自动释放池,优先级最高,保证创建释放池发生在其他所有回调之前。另一个是BeforeWaiting(准备进入休眠),在程序退出是释放自动释放池,优先级最低,保证其释放池子发生在其他所有回调之后。

关于方法调用的问题

NSobject调用performSelecter:afterDelay:方法或者performSelector:onThread: ,其实也会调用创建timer的方法。如果当前线程没有 RunLoop,则这个方法会失效。

关于UIImageView的延迟加载

滚动tableView的时候,UIImageView加载会有卡顿,此时,将设置图片的方法推迟到default里面performSelector:withObject:afterDelay:inModes可以较好地保存流畅性。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言 说道runloop,想必大家都只是稍微知道这玩意是干嘛的吧,以前也总是看这方面的书籍,并没有做下任何笔记,索...
    Mr姜饼阅读 3,685评论 1 5
  • 概述 RunLoop作为iOS中一个基础组件和线程有着千丝万缕的关系,同时也是很多常见技术的幕后功臣。尽管在平时多...
    sumrain_cloud阅读 4,472评论 0 5
  • RunLoop的定义与概念RunLoop的主要作用main函数中的RunLoopRunLoop与线程的关系RunL...
    __silhouette阅读 4,572评论 0 6
  • Runloop 1. 概述 一般来说,一个线程只能执行一个任务,执行完就会退出,如果我们需要一种机制,让线程能随时...
    极客学伟阅读 4,119评论 0 2
  • 最近因为天气不好,影响了我日更╯^╰ (路人甲:真实情况,某人体质不好,又生病了。) 咳咳,大家多注意身体啊~ 今...
    林佩纯阅读 890评论 0 3