iOS的NSRunLoop详解

最开始问大家几个问题:

1.应用程序在启动的时候是如何响应用户的手势操作呢?

2.主线程可以相应哪些事件呢?新开辟的一个子线程可以响应用户的滑动手势吗?

引入NSRunloop

NSRunLoop是iOS的CoreFoundation的一部分,Foundation对Core Foundation又做了一层封装。

每一个NSThread里边都有一个NSRunLoop,NSRunloop是一个响应事件处理的循环,当有事件传入的时候,执行,没有事件传入的时候,等待。一般来说我们不需要手动创建和启动NSRunloop。NSRunloop与线程是相互依存的关系

NSRunloop响应的事件包括两类:一是来自Input sources的异步事件,一是来自Timer sources的同步事件。

1.NSRunloop在一个线程中是一个单例

可以用[NSRunloop currentRunloop]获取单例

2.NSRunloop的启动

一般来说可以用:[[NSRunloop currentRunloop]run];来启动

3.NSRunloopMode

    Default模式

    定义:NSDefaultRunLoopMode(Cocoa)kCFRunLoopDefaultMode(Core Foundation)

    描述:默认模式中几乎包含了所有输入源(NSConnection除外),一般情况下应使用此模式。

    Connection模式

    定义:NSConnectionReplyMode(Cocoa)

    描述:处理NSConnection对象相关事件,系统内部使用,用户基本不会使用。

    Modal模式

    定义:NSModalPanelRunLoopMode(Cocoa)

    描述:处理modal panels事件。

    Event tracking模式

    定义:UITrackingRunLoopMode(iOS) NSEventTrackingRunLoopMode(cocoa)

    描述:在拖动loop或其他user interface tracking loops时处于此种模式下,在此模式下会限制输入事件的处理。例如,当手指按住         UITableView拖动时就会处于此模式。

    Common模式

    定义:NSRunLoopCommonModes(Cocoa)kCFRunLoopCommonModes(Core Foundation)

    描述:这是一个伪模式,其为一组run loop mode的集合,将输入源加入此模式意味着在Common Modes中包含的所有模式下都可以 处理。在Cocoa应用程序中,默认情况下Common Modes包含default modes,modal modes,event Tracking modes.可使           用CFRunLoopAddCommonMode方法想Common Modes中添加自定义modes。

3.currentMode属性

currentMode指的是该线程现在所处的运行模式

RunLoop在某一时刻只能且必须在一种特定运行模式下执行

更换Mode时,需要停止当前Loop,然后重启新Mode

Mode是iOS滑动顺畅的关键

4.一个线程可以处理多个RunloopMode的事件源

[[NSRunloop currentRunloop]addTimer: forRunloopMode:];

[[NSRunloop currentRunloop]addSelector: forRunloopMode:];

5.NSRunloop处于某个运行模式的时候,就会执行该运行模式下的所有的事件处理

比如用户滑动屏幕,那么操作系统会将NSRunloop切换到UITrackingRunLoopMode运行模式下,该运行模式对应的方法都会被执行

6.切换RunloopMode

目前切换RunloopMode是由操作系统来操作,不允许程序员手动调用

NSRunloop的用途

1.解决NSURLConnection在用户滚动UIScrollView或者UITableView不执行的问题

当使用NSURLConnection来加载文件的时候,如下面的代码:

NSURLConnection *connection = [[NSURLConnection alloc]

initWithRequest:request delegate:self startImmediately:NO];

[connection start];

NSURLConnection默认运行在default mode下,这样当用户在拖动UITableView处于UITrackingRunLoopMode模式时, NSURLConnection的数据也无法处理。

通过下面的方法可以解决这个问题:

[connection scheduleInRunLoop:[NSRunLoop currentRunLoop]

forMode:NSRunLoopCommonModes];

2.在后台线程运行NSURLConnection

通过CFRunLoopRun()使得后台线程一直执行,使用CFRunLoopStop(CFRunLoopGetCurrent())结束。

你可能感兴趣的:(iOS的NSRunLoop详解)