iOS多線程之理解RunLoop的CommonModes

iOS多線程之理解RunLoop的CommonModes

CFRunLoopModeRef (runloop運行模式)

RunLoop的運行模式(一共5種)git

- kCFRunLoopDefaultMode, App的默認運行模式,一般主線程是在這個運行模式下運行
- UITrackingRunLoopMode, 跟蹤用戶交互事件(用於 ScrollView 追蹤觸摸滑動,保證界面滑動時不受其餘Mode影響)
- kCFRunLoopCommonModes, 僞模式,不是一種真正的運行模式
- UIInitializationRunLoopMode:在剛啓動App時第進入的第一個Mode,啓動完成後就再也不使用
- GSEventReceiveRunLoopMode:接受系統內部事件,一般用不到

注意:多線程

1. RunLoop只會運行在一個模式下
2. 要切換模式,就要暫停當前模式,重寫啓動一個運行模式

特別的kCFRunLoopCommonModesapp

kCFRunLoopCommonModes是僞模式,指能夠在標記爲Common Modes的模式下運行

目前被標記爲Common Modes的模式: kCFRunLoopDefaultModeUITrackingRunLoopModeoop

如何理解runloop的 **kCFRunLoopCommonModes?**實現原理是怎樣?

首先,把一個NSTimer加入runloop,指定運行模式爲NSRunLoopCommonModes,並打印runloop線程

//初始化3個定時器,分別運行在不一樣的runloop模式
- (void)timerRunInRunLoop
{   
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    
    NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    [runLoop addTimer:timer forMode:NSDefaultRunLoopMode];

    NSTimer *timer2 = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run2) userInfo:nil repeats:YES];
    [runLoop addTimer:timer2 forMode:UITrackingRunLoopMode];

    NSTimer *timer3 = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run3) userInfo:nil repeats:YES];
    [runLoop addTimer:timer3 forMode:NSRunLoopCommonModes];
    NSLog(@"*********\n%@",runLoop);
}

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

- (void)run2
{
    NSLog(@"---UITrackingRunLoopMode");
}

- (void)run3
{
    NSLog(@"---NSRunLoopCommonModes");
}

這個runloop是app的主runloop,log太大,見附件 RunLoop實例Logcode

大體結構server

>current mode = kCFRunLoopDefaultMode ,//當前的運行模式
>common modes 
>common mode items
>modes
	>2 : name:UITrackingRunLoopMode, sources0, sources1, observers, timers
	>3 : name:GSEventReceiveRunLoopMode, sources0, sources1, observers, timers
	>4 : name:kCFRunLoopDefaultMode, sources0, sources1, observers, timers
	>5 : name:kCFRunLoopCommonModes, sources0, sources1, observers, timers

current mode

runloop當前運行模式對象

common modes

存儲的被標記爲common modes的模式事件

runloop_common_modes.png

common mode items

當前運行在common mode模式下的CFRunLoopSourceCFRunLoopObserverCFRunLoopTimerget

common mode items
.png

modes

modes裏面存的是各個運行模式下面,執行的sources,observers,timers

modes.png

咱們剛剛加載kCFRunLoopCommonModes的timer3在UITrackingRunLoopMode 和 kCFRunLoopDefaultMode下面的timers裏面都找到了,反而kCFRunLoopCommonModes下面沒有。而且kCFRunLoopCommonModes下面的sources,observers,timers什麼都沒有。這就不難理解爲何kCFRunLoopCommonModes爲何叫僞模式了。

總結

咱們能夠推導出kCFRunLoopCommonModes的實現原理。 執行[runLoop addTimer:timer3 forMode:NSRunLoopCommonModes]

1. 首先runloop對象到本身的common modes裏面拿出被標記的運行模式commonModes.
2. 匹配commonModes和modes->model->name.
3. 匹配成功的模式,將timer加入到對應model->timers裏面.
4. source, observer同timer.

文章包含的代碼:多線程demo

相關文章
相關標籤/搜索