Runloop学习笔记

此文仅为观后笔记!!!地址:http://v.youku.com/v_show/id_XODgxODkzODI0.html

Why Runloops ?

  • 是程序一直运行并接受用户输入;
  • 决定程序在何时应该处理哪些Event(事件);
  • 调用解耦(Message Queue);
  • 节省CPU时间

Runloops in Cocoa

Runloops in Cocoa
跟Runloop相关的东西
NSTimer、UIEvent、Autorelease、NSObject+NSDelayedPerforming、NSObject+NSThreadPerformAddition、CADisplayLink、CATransition、CAAnimation、dispatch_get_main_queue()、NSURLConnection

Runloop Callouts

6个调起函数

Runloop机制

runloop构成元素简图

RunloopTimer的封装

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;

+ (CADisplayLink *)displayLinkWithTarget:(id)target selector:(SEL)see;
- (void)addToRunLoop:(NSRunLoop *)runloop forMode:(NSRunLoopMode)mode;
.......

CFRunloopSource

  • source是Runloop的数据源抽象类(protocol);
  • Runloop定义了两个Version的Source:

    Source0:处理APP内部事件、APP自己负责管理(触发),如UIEvent、CFSocket;
    Source1:由Runloop和内核管理,mach port驱动,如:CFMachPort、CFMessagePort

  • 如有需要,可从中选择一种来实现自己的Source;
  • 当然基本不会出现上一条。

CFRunloopObserver

向外部报告Runloop当前状态的更改,框架中很多机制都由RunloopObserver触发,比如:CAAnimation

typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
    kCFRunLoopEntry = (1UL << 0),
    kCFRunLoopBeforeTimers = (1UL << 1),
    kCFRunLoopBeforeSources = (1UL << 2),
    kCFRunLoopBeforeWaiting = (1UL << 5),
    kCFRunLoopAfterWaiting = (1UL << 6),
    kCFRunLoopExit = (1UL << 7),
    kCFRunLoopAllActivities = 0x0FFFFFFFU
};
RunloopObserver与Autorelease Pool

UIKit通过RunloopObserver在Runloop两次Sleep减对AutoReleasePool进行Pop和Push,将这次Loop中产生的Autorelease对象释放。

CFRunLoopMode

  • Runloop在同一时间只能且必须在一种特定Mode下跑;
  • 更换Mode时,需要停止当前Loop,然后重启新Loop;
  • Mode是iOS App滑动顺畅的关键;
  • 可以自定义Mode(基本用不到)。
NSDefaultRunloopMode:默认状态,空闲状态。
UITrackingRunLoopMode:滑动ScrollView时,若想保证Timer不被ScrollView影响,则需添加到NSRunLoopCommonModes。
UIInitializationRunLoopMode:私有,App启动时。
NSRunLoopCommonModes:Mode集合

RunLoop与dispatch_get_main_queue()

GCD中dispatch到main queue的block被分发到main RunLoop执行。

RunLoop的挂起与唤醒

  • 指定用于唤醒的mach_port端口
  • 调用mach_msg监听唤醒端口,被唤醒前,系统内核将这个线程挂起,停留在mach_msg_trap状态;
  • 有另一个线程(或另一个进程中的某个线程)向内核发送这个端口的msg后,trap状态呗唤醒,RunLoop继续开始干活。


    伪代码

RunLoop实践

AFNetworking中RunLoop的创建

AFNetworking中RunLoop的创建

UITableView延迟加载图片的新思路

UITableView延迟加载图片

让Crash的App回光返照

接到Crash的Singal后手动重启RunLoop

Async Test Case

RunLoop sleep前验证

RunLoop源码

地址:https://opensource.apple.com/source/CF/CF-855.17/CFRunLoop.c.auto.html

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