读书人

iOS多线程编程Part 一/3 - NSThread amp;

发布时间: 2014-01-08 14:18:52 作者: rapoo

iOS多线程编程Part 1/3 - NSThread & Run Loop

Core Foundation层对应的是CFRunLoopRef:

iOS多线程编程Part 一/3 - NSThread & Run Loop

两组接口差不多,不过功能上还是有许多区别的,例如CF层可以添加自定义Input Source事件源(CFRunLoopSourceRef)和Run Loop观察者Observer(CFRunLoopObserverRef),很多类似功能的接口特性也是不一样的。

Run Loop运行

Run Loop如何运行呢?在上一节NSThread的入口函数中使用了一种NSRunLoop的使用场景,再看一例:

从上图可以看出Run Loop就是处理事件的一个循环,不同的是Timer Source事件处理后不会使Run Loop结束,而Input Source事件处理后会让Run Loop退出。因此你需要自己的一个Loop去不断运行Run Loop来处理事件,就像本文开头的示例那样。

细分下Run Loop的事件源:

1) Timer Souce就是创建Timer添加到Run Loop中,没啥好说的,Cocoa或者Core Foundation都有相应接口实现。需要注意的是scheduledTimerWith****开头生成的Timer会自动帮你以默认NSDefaultRunLoopMode模式加载到当前的Run Loop中,而其他接口生成的Timer则需要你手动使用-addTimer:forMode添加到Run Loop中。需要额外注意的是Timer的触发不会让Run Loop返回。(Timer sources deliver events to their handler routines but do not cause the run loop to exit.) 具体实验可以看下面的Sample Code。

2) Input Source中的-performSelector:***API调用簇方法,有以下这些接口:

主线程持有包含子线程的Run Loop和Source的context对象,还有一个用于保存需要运行操作的数据buffer。主线程需要子线程干活时,首先将需要的操作数据添加到数据buffer,然后通知source,唤醒子线程Run Loop(因为子线程可能正在sleep状态,CFRunLoopWakeUp唤醒Run Loop可以通知线程醒来干活),由于子线程也持有这个source和数据buffer,因此在触发唤醒时可以使用这个数据buffer的数据来执行相关操作(需要注意数据buffer访问时的同步)。

具体实现参见本文最后的Sample Code。

Run Loop的Observer

Core Foundation层的接口可以定义一个Run Loop的观察者在Run Loop进入以下某个状态时得到通知:

读书人网 >操作系统

热点推荐