Runloop-執行迴圈

weixin_34249678發表於2018-04-13

Runloop的目的何在
-保證程式不退出
-負責監聽事件:觸控、時鐘、網路事件
-如果沒有事件發生,會讓程式進入休眠狀態!

    NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
    //UITrackingRunLoopMode UI模式
    //NSDefaultRunLoopMode  預設模式
    //NSRunLoopCommonModes  佔位模式
//    [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
//    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
1908394-754928ba71587000.png
Runloop.png

——如果只使用NSDefaultRunLoopMode,因為UI模式優先順序最高,所以當使用者觸控的時候觸發UI模式,則預設模式下的計時器則不會被響應
——如果用UITrackingRunLoopMode,觸控的時候觸發UI模式,則UI模式下的計時器也會被響應,但是當觸控取消的時候,計時器也不會被響應了,因為只有觸控才會觸發UI模式
——使用NSRunLoopCommonModes,可以完美解決

讓執行緒有執行不完的任務!!執行緒就不會釋放了!!!
一條執行緒上面的Runloop模式是不迴圈的

@interface ViewController ()
@property (nonatomic,assign) BOOL isFinish;

@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];

    _isFinish = NO;
    //子執行緒
    NSThread *thread = [[NSThread alloc] initWithBlock:^{
        
        NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
        
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
        //Runloop---一條執行緒上面的Runloop模式是不迴圈的
        //最底層的 CFRunloop  currentRunloop()第一次獲取Runloop的時候,建立Runloop
        //[[NSRunLoop currentRunLoop] run];//死迴圈(這樣寫,執行緒幹不掉)

        if (!_isFinish) {
            [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.00001]];
        }
        NSLog(@"來了!!");

        //  while(true){
        //      //從事件佇列中取出來事件來處理
        //  }
    }];
    
    [thread start];
    
}

- (void)timerMethod{
    NSLog(@"%@",[NSThread currentThread]);
}
@end

runloop可以用來優化tableView上cell多張圖片,滑動卡頓的現象,因為渲染圖片也會阻塞執行緒,可以建立觀察者,將任務加到陣列中一個一個載入

相關文章