我收录的代码iOS技术点

RunLoop

2015-08-28  本文已影响309人  superWX

RunLoop

RunLoop就是运行循环,处理app中的各种事件(比如触摸事件,定时器事件,Selector事件)
一个线程对应一个RunLoop,主线程的RunLoop已经自动创建好了,子线程的RunLoop需要主动创建,RunLoop在第一次获取时创建,线程结束时销毁

RunLoop的获得

RunLoop相关类

RunLoop的组成

Mode

Mode代表RunLoop的运行模式。每次RunLoop职能指定一个Mode运行。切换Mode职能退出Loop,再重新指定一个Mode进入。
一个 RunLoop 包含若干个 Mode,每个Mode又包含若干个Source/Timer/Observer

系统默认的5个Mode

Timer

CFRunLoopTimerRef是基于时间的触发器

CFRunLoopTimerRef基本上说的就是NSTimer,它受RunLoop的Mode影响

GCD的定时器不受RunLoop的Mode影响

- (void)timer
{
    NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    // 定时器只运行在NSDefaultRunLoopMode下,一旦RunLoop进入其他模式,这个定时器就不会工作(比如textField的拖动)
    //    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    
    // 定时器只运行在UITrackingRunLoopMode下,一旦RunLoop进入其他模式,这个定时器就不会工作
    //    [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
    
    // 定时器会跑在标记为common modes的模式下
    // 标记为common modes的模式:UITrackingRunLoopMode和NSDefaultRunLoopMode
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}

- (void)timer2
{
    // 调用了scheduledTimer返回的定时器,已经自动被添加到当前runLoop中,而且是NSDefaultRunLoopMode
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    
    // 修改模式
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}

- (void)run
{
    NSLog(@"----run");
}

Source

事件的传入都是先传入Source1。然后再由Source1分发至source0进行处理。所以在函数调用栈中往往只看到Source0。

Obersver

CFRunLoopObserverRef是观察者,能够监听RunLoop的状态改变

/* Run Loop Observer Activities */
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
    kCFRunLoopEntry = (1UL << 0), // 1
    kCFRunLoopBeforeTimers = (1UL << 1), // 2
    kCFRunLoopBeforeSources = (1UL << 2), // 4
    kCFRunLoopBeforeWaiting = (1UL << 5), // 32
    kCFRunLoopAfterWaiting = (1UL << 6), // 64
    kCFRunLoopExit = (1UL << 7), // 128
    kCFRunLoopAllActivities = 0x0FFFFFFFU
};
- (void)observer
{
    // 创建observer
    CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
        NSLog(@"----监听到RunLoop状态发生改变---%zd", activity);
    });

    // 添加观察者:监听RunLoop的状态
    CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);
    
    // 释放Observer
    //凡是带有Create、Copy、Retain等字眼的函数,创建出来的对象,都需要在最后做一次release
    //比如CFRunLoopObserverCreate
    //release函数:CFRelease(对象);
    
    CFRelease(observer);
}

RunLoop处理逻辑

上一篇 下一篇

猜你喜欢

热点阅读