你好,歡迎來到IOS教程網

 Ios教程網 >> IOS訊息 >> 關於IOS >> IOS開發中NSRunloop跟NSTimer的問題

IOS開發中NSRunloop跟NSTimer的問題

編輯:關於IOS

在Windows時代,大家肯定對SendMessage,PostMessage,GetMessage有所了解,這些都是windows中的消息處理函數,那對應在ios中是什麼呢,其實就是NSRunloop這個東西。在ios中,所有消息都會被添加到NSRunloop中,分為‘input source’跟'timer source'種,並在循環中檢查是不是有事件需要發生,如果需要那麼就調用相應的函數處理。

  我們在使用NSTimer的時候,可能會接觸到runloop的概念,下面是一個簡單的例子:   復制代碼  1 - (void)viewDidLoad  2 {  3     [super viewDidLoad];  4     // Do any additional setup after loading the view, typically from a nib.  5     NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:1  6                                               target:self  7                                             selector:@selector(printMessage:)  8                                             userInfo:nil  9                                              repeats:YES]; 10 } 復制代碼 這個時候如果我們在界面上滾動一個scrollview,那麼我們會發現在停止滾動前,控制台不會有任何輸出,就好像scrollView在滾動的時候將timer暫停了一樣,在查看相應文檔後發現,這其實就是runloop的mode在做怪。 runloop可以理解為cocoa下的一種消息循環機制,用來處理各種消息事件,我們在開發的時候並不需要手動去創建一個runloop,因為框架為我們創建了一個默認的runloop,通過[NSRunloop currentRunloop]我們可以得到一個當前線程下面對應的runloop對象,不過我們需要注意的是不同的runloop之間消息的通知方式。   接著上面的話題,在開啟一個NSTimer實質上是在當前的runloop中注冊了一個新的事件源,而當scrollView滾動的時候,當前的MainRunLoop是處於UITrackingRunLoopMode的模式下,在這個模式下,是不會處理NSDefaultRunLoopMode的消息(因為RunLoop Mode不一樣),要想在scrollView滾動的同時也接受其它runloop的消息,我們需要改變兩者之間的runloopmode.   1 [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 簡單的說就是NSTimer不會開啟新的進程,只是在Runloop裡注冊了一下,Runloop每次loop時都會檢測這個timer,看是否可以觸發。當Runloop在A mode,而timer注冊在B mode時就無法去檢測這個timer,所以需要把NSTimer也注冊到A mode,這樣就可以被檢測到。   說到這裡,在http異步通信的模塊中也有可能碰到這樣的問題,就是在向服務器異步獲取圖片數據通知主線程刷新tableView中的圖片時,在tableView滾動沒有停止或用戶手指停留在屏幕上的時候,圖片一直不會出來,可能背後也是這個runloop的mode在做怪,嘿嘿。
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved