iOS - OC RunLoop 運行循環/消息循環


1、RunLoop

  • 1)運行循環:

    • 運行循環在 iOS 開發中幾乎不用,但是概念的理解卻非常重要。

    • 同一個方法中的代碼一般都在同一個運行循環中執行,運行循環監聽 UI 界面的修改事件,待本次運行循環結束時,統一將界面的修改渲染出來。

    • 點擊事件觸發結束后立即結束本次運行循環。

    • 作用:

      • 保證程序不退出。
      • 負責監聽所有事件,例如:手勢觸摸,時鍾觸發,網絡加載數據完成等。
    • 特性:

      • 沒有事件時,會休眠(省電),一旦監聽到事件,會立即響應。
      • 每一個線程都有一個 runloop,但是只有主線程的 runloop 會默認啟動。子線程的運行循環默認是不啟動的。
  • 2)子線程運行循環:

    • 子線程的運行循環默認是不啟動的。

    • 啟動運行循環后,如果不停止運行循環,不會執行后續的任何代碼,會形成一個死循環。

    • 一旦停止了運行循環,后續代碼能夠執行,執行完畢后,線程被自動銷毀。

  • 3)響應者鏈條事件監聽過程:

    RunLoop1

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());
    		}
    	}
    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM