iOS SDK详解之Runloop

Runloop是iOS中用于高效处理任务的机制,每个线程都有一个Runloop,主线程Runloop在App启动时自动运行。Runloop通过input sources和timers处理事件,其模式切换确保了任务的有序执行。在特定模式下,如UITrackingRunLoopMode,某些任务(如滚动)会优先处理,避免timer干扰。使用Observer可以监听Runloop状态,后台线程使用Runloop需配置Input Source以避免立即退出。
摘要由CSDN通过智能技术生成

原创Blog,转载请注明出处
http://blog.csdn.net/hello_hwc?viewmode=list
我的stackoverflow

profile for Leo on Stack Exchange, a network of free, community-driven Q&A sites


前言:Runloop多线程开发的中的一个概念,当然也可以向Runloop中提交一些任务,监听一些事件。属于多线程编程的一部分,合理的使用Runloop对App的性能提高有很大帮助。


关于Runloop 的官方资料

笔者也是主要从三个链接中理解和概括的,如果英文好的同学,同时觉得自己对Runloop的理解不够,还是建议自习读读官方的文档,那是最权威的东西。


什么是Runloop

Runloop是为了让线程高效处理任务而创建的机制。一个Runloop就是一个事件处理循环(Event processing loop),通过Runloop可以执行一些计划任务,接受一些事件。Runloop的特点是能够在有任务的时候让线程被唤醒,而没有任务的时候线程休眠


Runloop与线程的关系

在iOS开发中,每个线程(NSThread)在创建的时候都会自动绑定一个Runloop。主线程的Runloop在App启动的时候自动运行。自己创建的线程,要写代码来启动Runloop,提交任务,接受事件。


RunLoop的运行机制

Runloop和它的名字很像,他就是线程运行的一个循环,通过这个循环可以处理事件回调。Runloop从两个源头接收事件

从input sources接收异步事件,来源通常是从其其它线程或者其他应用

从Timer sources接收同步事件,这种事件是在指定时间触发的

除了提供回调之外,Runloop还能触发一些Notification来告诉观察者当前Runloop处于的状态。

我们再来看看iOS中,与Runloop相关的数据类型

NSRunLoop ,面相对象的方式处理Runloop,非线程安全

CFRunLoop ,C相关的关于Runloop的函数,线程安全

CFRunLoopSource,一种抽象的表示input source的对象,这种对象可以被加入到Runloop中,并且产生异步回调。例如网络数据到达,或者用户操作。CFRunLoopSource一共有两种类型,Version 0 Source 和Version 1 Source。(之所以这样命名,是因为其内部实现的有个version字段对应的是0/1)

  • Version 0 Source,这种source要应用自己管理,当这种source触发的时候,需要程序手动调用CFRunLoopSourceSignal 来触发。CFSocket就是这种Source。
  • Version1 Source,这种Source由内核和Runloop自动管理。当这种Source能够触发的时候,使用Mach ports 来通知Source。也就是说,当Mach ports 接收到可以触发的消息时候,内核自动触发这种Source

简单理解,由应用发起的任务就是Version 0,其余是Source 1

CFRunLoopTimer,是一种特别得Source,在将来的某一时间点触发。注意,这个timer的触发事件并不是精确的。当Timer所处的Mode并没有在运行,或者一个长时间的回调在执行。Timer会延迟到下一个Runloop再判断是否要触发。CFRunLoopTimer与NSTimer是toll-free bridged,意味着传入NSTimer *的地方就可以传入CFRunLoopTimerRef

CFRunLoopObserver,通过CFRunLoopObserver可以监听Runloop执行过程中的不同状态。例如开始一个Loop,结束一个Loop等。


Runloop Mode

Runloop Mode可以理解为运行模式,每个运行模式中包含了input sources和time sources以及observers,Runloop可以在多个运行模式中切换。只有处于Runloop当前模式中的timer,sources以及observers才是有效的。

通过模式切换,可以过滤掉不想要的事件,有选择的处理任务,使得各种mode相互不影响。比如主线程的Runloop就有两个模式kCFRunLoopDefaultMode和UITrackingRunLoopMode。其中,默认是运行在kCFRunLoopDefaultMode。在监听用户持续触摸的时候会切换到UITrackingRunLoopMode。所以,在Scrollview滚动的时候,添加的timer会失效,来保证滚动的流畅性。

Mode分为两种,Core Foundation预置的有几种,当然也可以自己通过CFRunloop相关API创建Mode,不同Mode按照name来区分。

预定义的几种Mode

  1. kCFRunLoopDefaultMode 默认的模式,大多数情况下都适用默认模式
  2. UITrackingRunLoopMode,接收到用户的持续触摸时候切换到的模式。
  3. kCFRunLoopCommonModes ,common mode,当像common mode中添加input source时候,也会像在标注为common mode的其他添加。(注意,不包括observer以及timer)

input Source

实际开发中常用的提交Source的是这一组列代码。这一组代码提交的Source是序列化的提交到一个线程上的,解决了很多在一个线程上执行多任务的问题。在执行完后,source会自动释放,使用这一组代码,可以向任何线程传递消息

performSelectorOnMainThread:withObject:waitUntilDone:
performSelectorOnMainThread:withObject:waitUntilDone:modes:
performSelector:onThread:withObject:waitUntilDone
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值