1、RunLoop
-
1)運行循環:
-
運行循環在 iOS 開發中幾乎不用,但是概念的理解卻非常重要。
-
同一個方法中的代碼一般都在同一個運行循環中執行,運行循環監聽 UI 界面的修改事件,待本次運行循環結束時,統一將界面的修改渲染出來。
-
點擊事件觸發結束后立即結束本次運行循環。
-
作用:
- 保證程序不退出。
- 負責監聽所有事件,例如:手勢觸摸,時鍾觸發,網絡加載數據完成等。
-
特性:
- 沒有事件時,會休眠(省電),一旦監聽到事件,會立即響應。
- 每一個線程都有一個 runloop,但是只有主線程的 runloop 會默認啟動。子線程的運行循環默認是不啟動的。
-
-
2)子線程運行循環:
-
子線程的運行循環默認是不啟動的。
-
啟動運行循環后,如果不停止運行循環,不會執行后續的任何代碼,會形成一個死循環。
-
一旦停止了運行循環,后續代碼能夠執行,執行完畢后,線程被自動銷毀。
-
-
3)響應者鏈條事件監聽過程:
2、運行循環的使用
2.1 時鍾調度
/*
- (void)addTimer:(NSTimer *)timer forMode:(NSString *)mode;
NSDefaultRunLoopMode: 時鍾,網絡。 發生用戶交互的時候,時鍾會被暫停
NSRunLoopCommonModes: 用戶交互,響應級別高。 發生用戶交互的時候,時鍾仍然會觸發,如果時鍾觸發方法非常耗時,
使用此方式時用戶操作會造成非常嚴重的卡頓。
*/
-
以 NSRunLoopCommonModes 方式創建
// 調度時鍾 self.timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(updateTimer) userInfo:nil repeats:YES]; // 將時鍾以 NSRunLoopCommonModes 模式添加到運行循環 [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
-
以 NSDefaultRunLoopMode 方式創建
// 調度時鍾 /* 默認將時鍾以 NSDefaultRunLoopMode 模式添加到運行循環 */ self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTimer) userInfo:nil repeats:YES];
-
子線程運行循環
dispatch_async(dispatch_get_global_queue(0, 0), ^{ // 在子線程開啟時鍾,由於子線程的運行循環沒有啟動,所以沒法監聽時鍾事件 self.timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(updateTimer) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode]; // 啟動子線程的運行循環,這句代碼就是一個死循環!如果不停止運行循環,不會執行后續的任何代碼 CFRunLoopRun(); // 停止子線程運行循環之前,不會執行添加到此處的任何代碼 }); // 運行循環執行操作方法 - (void)updateTimer { static int num = 0; NSLog(@"%d %@", num++, [NSThread currentThread]); // 滿足條件后,停止當前的運行循環 if (num == 8) { // 一旦停止了運行循環,后續代碼能夠執行,執行完畢后,線程被自動銷毀 CFRunLoopStop(CFRunLoopGetCurrent()); } }