16 - RunLoop

2017-07-02  本文已影响11人  RadioWaves

1 - RunLoop - 运行循环

1 - 基本作用:



2 - RunLoop对象

3 - RunLoop与线程

4 - 获得RunLoop对象

#Foundation中
// 获得当前线程的RunLoop对象
[NSRunLoop currentRunLoop];                             
// 获得主线程的RunLoop对象
[NSRunLoop mainRunLoop];                                   

#Core Foundation中
// 获得当前线程的RunLoop对象
CFRunLoopGetCurrent();                                  
// 获得主线程的RunLoop对象
CFRunLoopGetMain();                                    

RunLoop处理逻辑-官方版


RunLoop的事件队列

RunLoop处理逻辑-网友整理版



2 - RunLoop相关类

由于苹果公司只暴露了RunLoop类,无聊了解的更加清楚,所以只能查看C语言的RunLoop。
C语言的RunLoop以及runtime都是开源的:http://opensource.apple.com.

Core Foundation中关于RunLoop的5个类:

  1. CFRunLoopRef --- RunLoop本身
  2. CFRunLoopModeRef --- RunLoop的运行模式
  3. CFRunLoopSourceRef --- RunLoop的事件源
  4. CFRunLoopObserverRef --- RunLoop的观察者/监听者
  5. CFRunLoopTimerRef --- RunLoop的定时器
一个RunLoop对象想要跑起来,内部必须包含Mode,而Mode内部也必须包含若干个Source/Observer/Timer,否则是无法循环的

CF的内存管理(Core Foundation)
凡是带有CreateCopyRetain等字眼的函数,创建出来的对象,都需要在最后做一次release

CFRunLoopObserverCreate
release函数:CFRelease(对象);

2.1 - CFRunLoopModeRef(运行模式)

CFRunLoopModeRef代表RunLoop的运行模式.

2.2 - CFRunLoopTimerRef (定时器)

示例1

需求:图片中是textView控件,当正在滚动textView的时候,不让定时器,打印


解决方案:


Snip20161027_24.png
    NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

示例2

还按照上面的例子来说,如果我想textView无论是滚动还是不滚动的情况下,定时器依然有打印该怎么弄呢?
这个时候我们可以将Mode换种模式就可以了。

Snip20161028_27.png
按照图片的显示,进入头文件后可以看到两种Mode。
一种是NSDefaultRunLoopMode一种是NSRunLoopCommonModes.
我们使用第二种就可以了
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode: NSRunLoopCommonModes];

运行后,打印下currentRunLoop内部的东西,我们来看下。



从log上就可以看出当前的RunLoop内部包含了2种Mode。无论是在textView静止或者滚动的状态,textView都是会打印的。

示例3

还按照上面的例子来说,如果我想textView只在textView滚动的时候定时器才有打印该怎么弄呢?
这个时候我们可以将Mode换成UITrackingRunLoopMode就可以了、


可是这个时候我们可以看到,进入Mode的头文件是看不到UITrackingRunLoopMode,这个时候可以看到UITrackingRunLoopMode是以UI开头的,所以要进到UIKit框架才可以看到

关于ScheduledTimer

Snip20161028_33.png

关于往RunLoop的Mode中添加timer的方式

添加timer只有这一种方式

关于CADisplayLink


2.3 - CFRunLoopSourceRef(事件源)

CFRunLoopSourceRef一般是由系统来决定的。
CFRunLoopSourceRef一般是事件。 比如:点击事件,触摸事件...都是处于Source中。



Source1是不会在函数调用栈显示的,Source1会先接收事件,比如触摸了屏幕硬件的表面,然后通过Source1包装成Event分发给Source0来处理 查看函数调用栈

2.4 - CFRunLoopObserverRef(观察者/监听者)

想添加Observer只能通过C语言的代码来添加。

代码实现

Warning:

由于是用C语言创建的Observer所以,
凡是带有create /copy/retain等字眼创建的函数,创建出来的对象,都需要在最后做一次release

上一篇 下一篇

猜你喜欢

热点阅读