IOS開發中NSRunloop跟NSTimer的問題

在Windows時代,你們確定對SendMessage,PostMessage,GetMessage有所瞭解,這些都是windows中的消息處理函數,那對應在ios中是什麼呢,其實就是NSRunloop這個東西。在ios中,全部消息都會被添加到NSRunloop中,分爲‘input source’跟'timer source'種,並在循環中檢查是否是有事件須要發生,若是須要那麼就調用相應的函數處理。ios

咱們在使用NSTimer的時候,可能會接觸到runloop的概念,下面是一個簡單的例子:windows

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:1
                                              target:self
                                            selector:@selector(printMessage:)
                                            userInfo:nil
                                             repeats:YES];
}

 

這個時候若是咱們在界面上滾動一個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在作怪,嘿嘿。函數

轉載:http://blog.csdn.net/yuquan0821/article/details/16843195oop

參考:http://w11h22j33.iteye.com/blog/1998620.net

http://blog.csdn.net/lengshengren/article/details/12905627線程

相關文章
相關標籤/搜索