57 NSRunLoop






NSRunLoop





57

NSRunLoop

1.NSRunLoop是消息機制的處理模式
NSRunLoop的作用在於有事情做的時候使的當前NSRunLoop的線程工作,沒有事情做讓當前NSRunLoop的線程休眠

2.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的釋放

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

4.runloopmode是一個集合,包括監聽:事件源,定時器,以及需通知的runloop observers
模式包括:
default模式:幾乎包括所有輸入源(除NSConnection) NSDefaultRunLoopMode模式 
mode模式:處理modal panels
connection模式:處理NSConnection事件,屬於系統內部,用戶基本不用
event tracking模式:如組件拖動輸入源 UITrackingRunLoopModes 不處理定時事件 
common modes模式:NSRunLoopCommonModes 這是一組可配置的通用模式。將input sources與該模式關聯則同時也將input sources與該組中的其它模式進行了關聯。 

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



例:
1).在timer與table同時執行情況,當拖動table時,runloop進入UITrackingRunLoopModes模式下,不會處理定時事件,此時timer不能處理,所以此時將timer加入到NSRunLoopCommonModes模式(addTimer forMode)
2).在scroll一個頁面時來鬆開,此時connection不會收到消息,由於scroll時runloop爲UITrackingRunLoopModes模式,不接收輸入源,此時要修改connection的mode
[scheduleInRunLoop:[NSRunLoop currentRunLoop]forMode:NSRunLoopCommonModes];

5.關於-(BOOL)runMode:(NSString *)mode beforeDate:(NSDate *)date;方法
指定runloop模式來處理輸入源,首個輸入源或date結束退出。
暫停當前處理的流程,轉而處理其他輸入源,當date設置爲[NSDate distantFuture](將來,基本不會到達的時間),所以除非處理其他輸入源結束,否則永不退出處理暫停的當前處理的流程。

6.while(A){
 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 
}
當前A爲YES時,當前runloop會一直接收處理其他輸入源,當前流程不繼續處理,出爲A爲NO,當前流程繼續

7.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。

8.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裏的方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章