NSRunLoop詳解


1.NSRunLoop是IOS消息機制的處理模式 異步

NSRunLoop的主要做用:控制NSRunLoop裏面線程的執行和休眠,在有事情作的時候使當前NSRunLoop控制的線程工做,沒有事情作讓當前NSRunLoop的控制的線程休眠。 async

2.NSRunLoop 就是一直在循環檢測,從線程start到線程end,檢測inputsource(如點擊,雙擊等操做)同步事件,檢測timesource同步事件,檢測到輸入源會執行處理函數,首先會產生通知,corefunction向線程添加runloop observers來監聽事件,意在監聽事件發生時來作處理。 3.runloopmode是一個集合,包括監聽:事件源,定時器,以及需通知的runloop observers 模式包括: 函數

default模式:幾乎包括全部輸入源(除NSConnection) NSDefaultRunLoopMode模式  mode模式:處理modal panels oop

connection模式:處理NSConnection事件,屬於系統內部,用戶基本不用 spa

event tracking模式:如組件拖動輸入源 UITrackingRunLoopModes 不處理定時事件  線程

common modes模式:NSRunLoopCommonModes 這是一組可配置的通用模式。將input sources與該模式關聯則同時也將input sources與該組中的其它模式進行了關聯。  orm

每次運行一個run loop,你指定(顯式或隱式)run loop的運行模式。當相應的模式傳遞給run loop時,只有與該模式對應的 input sources才被監控並容許run loop對事件進行處理(與此相似,也只有與該模式對應的observers纔會被通知) server

5.NSTimer默認添加到當前NSRunLoop中,也能夠手動制定添加到本身新建的NSRunLoop的中 對象

[NSTimer schduledTimerWithTimeInterval: target:selector:userInfo:repeats]; 此方法默認添加到當前NSRunLoop中 事件

NSTimer *timer = [NSTimer timerWithTimeInterval: invocation:repeates:]; NSTimer *timer = [[NSTimer alloc] initWithFireDate:...]; 

建立timer  [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];  注意 timer的釋放    

例: 

1). 在timer與table同時執行狀況,當拖動table時,runloop進入UITrackingRunLoopModes模式下,不會處理定時事件,此時timer不能處理,因此此時將timer加入到NSRunLoopCommonModes模式(addTimer forMode) 

2).在滾動一個頁面時來鬆開,此時connection不會收到消息,因爲scroll時runloop爲UITrackingRunLoopModes模式,不接收輸入源,此時要修改connection的mode [scheduleInRunLoop:[NSRunLoop currentRunLoop]forMode:NSRunLoopCommonModes]; 六、子線程中的NSRunLoop須要手動啓動,在子線程中使用timer要啓動NSRunLoop。 七、關於-(BOOL)runMode:(NSString *)mode beforeDate:(NSDate *)date;方法 指定runloop模式來處理輸入源,首個輸入源或date結束退出。 

暫停當前處理的流程,轉而處理其餘輸入源,當date設置爲[NSDate distantFuture](未來,基本不會到達的時間),因此除非處理其餘輸入源結束,不然永不退出處理暫停的當前處理的流程。 8.while(A){ 

 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];  } 

當前A爲YES時,當前runloop會一直接收處理其餘輸入源,當前流程不繼續處理,出爲A爲NO,當前流程繼續 

9 、perform selector在thread中被序列化執行,這樣就緩和了許多在同一個thread中運行多個方法所產生的同步問題。perform selector source在運行完selector後自動從run loop中移除。 當在非main thread中perform selector時,其thread中必須有一個激活的run loop。對於你本身建立的thread而言,只有你的代碼顯式的運行一個run loop後該perform selector才能獲得執行。Run loop在當loop運行時處理全部已排隊的perform selector,而不是在一個loop循環時只處理某一個perform selector。  

10.performSelector 關於內存管理的執行原理是這樣的執

行 [self performSelector:@selector(method1:) withObject:self.tableLayer afterDelay:3]; 的時候,系統會將tableLayer的引用計數加1,執行完這個方法時,還會將tableLayer的引用計數減1,因爲延遲這時tableLayer的引用計數沒有減小到0,也就致使了切換場景dealloc方法沒有被調用,出現了內存泄露。 利用以下函數: 

[NSObject cancelPreviousPerformRequestsWithTarget:self] 固然你也能夠一個一個得這樣用: 

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(method1:) object:nil] 


加上了這個之後,順利地執行了dealloc方法  

在touchBegan裏面 

[self performSelector:@selector(longPressMethod:) withObject:nil afterDelay:longPressTime] 而後在end 或cancel裏作判斷,若是時間不夠長按的時間調用: 

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(longPressMethod:) object:nil] 

取消began裏的方法  

**********************************如下是我在cocoachina中看到的一份總結 轉載過來 線程實現的幾種方式: 

1. Operation Objects   // NSOperation及相關子類 

2. *****                           // dispatch_async等相關函數 

3. Idle-time notifications  //  NSNotificationQueue,低優先級 3. Asynchronous functions  // 異步函數 4. Timers                      // NSTimer 5. Separate processes  // 沒用過  

線程建立的成本: 

kernel data structures  約1KB 

Stack space             512KB(secondary threads)                                     1MB(iOS main thread) Creation time           約90 microseconds  

Run Loop和線程的關係: 

1. 主線程的run loop默認是啓動的,用於接收各類輸入sources 

2. 對第二線程來講,run loop默認是沒有啓動的,若是你須要更多的線程交互則能夠手動配置和啓動,若是線程執行一個長時間已肯定的任務則不須要。  

Run Loop什麼狀況下使用: 

a. 使用ports 或 input sources 和其餘線程通訊   // 不瞭解 

b. 在線程中使用timers                                             // 若是不啓動run loop,timer的事件是不會響應的  

c. 在Cocoa 應用中使用performSelector...方法   // 應該是performSelector...這種方法會啓動一個線程並啓動run loop吧 

d. 讓線程執行一個週期性的任務                            // 若是不啓動run loop, 線程跑完就可能被系統釋放了  

注:timer的建立和釋放必須在同一線程中。 

[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];  此方法會retain timer對象的引用計數 

相關文章
相關標籤/搜索