關(guān)于NSRunLoop

1.NSRunLoop是消息機(jī)制的處理模式

NSRunLoop的作用在于有事情做的時(shí)候使的當(dāng)前NSRunLoop的線程工作,沒(méi)有事情做讓當(dāng)前NSRunLoop的線程休眠

2.nstimer默認(rèn)添加到當(dāng)前NSRunLoop中,也可以手動(dòng)制定添加到自己新建的NSRunLoop的中

[NSTimer?schduledTimerWithTimeInterval:?target:selector:userInfo:repeats];

此方法默認(rèn)添加到當(dāng)前NSRunLoop中

NSTimer?*timer?=?[NSTimer?timerWithTimeInterval:?invocation:repeates:];

NSTimer?*timer?=?[[NSTimer?alloc]?initWithFireDate:...];

創(chuàng)建timer??[[NSRunLoop?currentRunLoop]addTimer:timer?forMode:NSRunLoopCommonModes];

注意?timer的釋放

3.NSRunLoop就是一直在循環(huán)檢測(cè),從線程start到線程end,檢測(cè)inputsource(如點(diǎn)擊,雙擊等操作)同步事件,檢測(cè)timesource同步事件,檢測(cè)到輸入源會(huì)執(zhí)行處理函數(shù),首先會(huì)產(chǎn)生通知,corefunction向線程添加runloop?observers來(lái)監(jiān)聽(tīng)事件,意在監(jiān)聽(tīng)事件發(fā)生時(shí)來(lái)做處理。

4.runloopmode是一個(gè)集合,包括監(jiān)聽(tīng):事件源,定時(shí)器,以及需通知的runloop?observers

模式包括:

default模式:幾乎包括所有輸入源(除NSConnection)?NSDefaultRunLoopMode模式

mode模式:處理modal?panels

connection模式:處理NSConnection事件,屬于系統(tǒng)內(nèi)部,用戶(hù)基本不用

event?tracking模式:如組件拖動(dòng)輸入源?UITrackingRunLoopModes?不處理定時(shí)事件

common?modes模式:NSRunLoopCommonModes?這是一組可配置的通用模式。將input?sources與該模式關(guān)聯(lián)則同時(shí)也將input?sources與該組中的其它模式進(jìn)行了關(guān)聯(lián)。

每次運(yùn)行一個(gè)run?loop,你指定(顯式或隱式)run?loop的運(yùn)行模式。當(dāng)相應(yīng)的模式傳遞給run?loop時(shí),只有與該模式對(duì)應(yīng)的input?sources才被監(jiān)控并允許run?loop對(duì)事件進(jìn)行處理(與此類(lèi)似,也只有與該模式對(duì)應(yīng)的observers才會(huì)被通知)

例:

1).在timer與table同時(shí)執(zhí)行情況,當(dāng)拖動(dòng)table時(shí),runloop進(jìn)入U(xiǎn)ITrackingRunLoopModes模式下,不會(huì)處理定時(shí)事件,此時(shí)timer不能處理,所以此時(shí)將timer加入到NSRunLoopCommonModes模式(addTimer?forMode)

2).在scroll一個(gè)頁(yè)面時(shí)來(lái)松開(kāi),此時(shí)connection不會(huì)收到消息,由于scroll時(shí)runloop為UITrackingRunLoopModes模式,不接收輸入源,此時(shí)要修改connection的mode

[scheduleInRunLoop:[NSRunLoop?currentRunLoop]forMode:NSRunLoopCommonModes];

5.關(guān)于-(BOOL)runMode:(NSString?*)mode?beforeDate:(NSDate?*)date;方法

指定runloop模式來(lái)處理輸入源,首個(gè)輸入源或date結(jié)束退出。

暫停當(dāng)前處理的流程,轉(zhuǎn)而處理其他輸入源,當(dāng)date設(shè)置為[NSDate?distantFuture](將來(lái),基本不會(huì)到達(dá)的時(shí)間),所以除非處理其他輸入源結(jié)束,否則永不退出處理暫停的當(dāng)前處理的流程。

6.while(A){

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

}

當(dāng)前A為YES時(shí),當(dāng)前runloop會(huì)一直接收處理其他輸入源,當(dāng)前流程不繼續(xù)處理,出為A為NO,當(dāng)前流程繼續(xù)

7.perform?selector在thread中被序列化執(zhí)行,這樣就緩和了許多在同一個(gè)thread中運(yùn)行多個(gè)方法所產(chǎn)生的同步問(wèn)題。perform?selector?source在運(yùn)行完selector后自動(dòng)從run?loop中移除。

當(dāng)在非main?thread中perform?selector時(shí),其thread中必須有一個(gè)激活的run?loop。對(duì)于你自己創(chuàng)建的thread而言,只有你的代碼顯式的運(yùn)行一個(gè)run?loop后該perform?selector才能得到執(zhí)行。Run?loop在當(dāng)loop運(yùn)行時(shí)處理所有已排隊(duì)的perform?selector,而不是在一個(gè)loop循環(huán)時(shí)只處理某一個(gè)perform?selector。

8.performSelector關(guān)于內(nèi)存管理的執(zhí)行原理是這樣的執(zhí)行?[self?performSelector:@selector(method1:)?withObject:self.tableLayer?afterDelay:3];?的時(shí)候,系統(tǒng)會(huì)將tableLayer的引用計(jì)數(shù)加1,執(zhí)行完這個(gè)方法時(shí),還會(huì)將tableLayer的引用計(jì)數(shù)減1,由于延遲這時(shí)tableLayer的引用計(jì)數(shù)沒(méi)有減少到0,也就導(dǎo)致了切換場(chǎng)景dealloc方法沒(méi)有被調(diào)用,出現(xiàn)了內(nèi)存泄露。

利用如下函數(shù):

[NSObject?cancelPreviousPerformRequestsWithTarget:self]

當(dāng)然你也可以一個(gè)一個(gè)得這樣用:

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

加上了這個(gè)以后,順利地執(zhí)行了dealloc方法

在touchBegan里面

[self?performSelector:@selector(longPressMethod:)?withObject:nil?afterDelay:longPressTime]

然后在end?或cancel里做判斷,如果時(shí)間不夠長(zhǎng)按的時(shí)間調(diào)用:

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

取消began里的方法

**********************************以下是我在cocoachina中看到的一份總結(jié)?轉(zhuǎn)載過(guò)來(lái)

線程實(shí)現(xiàn)的幾種方式:

1.?Operation?Objects???//?NSOperation及相關(guān)子類(lèi)

2.?*****???????????????????????????//?dispatch_async等相關(guān)函數(shù)

3.?Idle-time?notifications??//??NSNotificationQueue,低優(yōu)先級(jí)

3.?Asynchronous?functions??//?異步函數(shù)

4.?Timers??????????????????????//?NSTimer

5.?Separate?processes??//?沒(méi)用過(guò)

線程創(chuàng)建的成本:

kernel?data?structures??約1KB

Stack?space?????????????512KB(secondary?threads)

1MB(iOSmain?thread)

Creation?time???????????約90?microseconds

Run?Loop和線程的關(guān)系:

1.?主線程的run?loop默認(rèn)是啟動(dòng)的,用于接收各種輸入sources

2.?對(duì)第二線程來(lái)說(shuō),run?loop默認(rèn)是沒(méi)有啟動(dòng)的,如果你需要更多的線程交互則可以手動(dòng)配置和啟動(dòng),如果線程執(zhí)行一個(gè)長(zhǎng)時(shí)間已確定的任務(wù)則不需要。

Run?Loop什么情況下使用:

a.?使用ports?或?input?sources?和其他線程通信???//?不了解

b.?在線程中使用timers?????????????????????????????????????????????//?如果不啟動(dòng)run?loop,timer的事件是不會(huì)響應(yīng)的

c.?在Cocoa?應(yīng)用中使用performSelector...方法???//?應(yīng)該是performSelector...這種方法會(huì)啟動(dòng)一個(gè)線程并啟動(dòng)run?loop吧

d.?讓線程執(zhí)行一個(gè)周期性的任務(wù)????????????????????????????//?如果不啟動(dòng)run?loop,?線程跑完就可能被系統(tǒng)釋放了

注:timer的創(chuàng)建和釋放必須在同一線程中。

[[NSRunLoop?currentRunLoop]?addTimer:timer?forMode:NSRunLoopCommonModes];??此方法會(huì)retain?timer對(duì)象的引用計(jì)數(shù)。

何時(shí)使用Run Loop

僅當(dāng)在為你的程序創(chuàng)建輔助線程的時(shí)候,你才需要顯式運(yùn)行一個(gè) run loop。Run loop 是程序主線程基礎(chǔ)設(shè)施的關(guān)鍵部分。所以,Cocoa 和 Carbon 程序提供了代碼運(yùn) 行主程序的循環(huán)并自動(dòng)啟動(dòng) run loop。IOS 程序中 UIApplication 的 run 方法(或 Mac OS X 中的 NSApplication)作為程序啟動(dòng)步驟的一部分,它在程序正常啟動(dòng)的時(shí) 候就會(huì)啟動(dòng)程序的主循環(huán)。類(lèi)似的,RunApplicationEventLoop 函數(shù)為 Carbon 程序 啟動(dòng)主循環(huán)。如果你使用 xcode 提供的模板創(chuàng)建你的程序,那你永遠(yuǎn)不需要自己去顯 式的調(diào)用這些例程。

對(duì)于輔助線程,你需要判斷一個(gè) run loop 是否是必須的。如果是必須的,那么 你要自己配置并啟動(dòng)它。你不需要在任何情況下都去啟動(dòng)一個(gè)線程的 run loop。比 如,你使用線程來(lái)處理一個(gè)預(yù)先定義的長(zhǎng)時(shí)間運(yùn)行的任務(wù)時(shí),你應(yīng)該避免啟動(dòng) run loop。Run loop 在你要和線程有更多的交互時(shí)才需要,比如以下情況:

?使用端口或自定義輸入源來(lái)和其他線程通信

?使用線程的定時(shí)器

?Cocoa 中使用任何 performSelector...的方法

?使線程周期性工作

如果你決定在程序中使用 run loop,那么它的配置和啟動(dòng)都很簡(jiǎn)單。和所有線程 編程一樣,你需要計(jì)劃好在輔助線程退出線程的情形。讓線程自然退出往往比強(qiáng)制關(guān) 閉它更好。關(guān)于更多介紹如何配置和退出一個(gè) run loop,參閱”使用 Run Loop 對(duì)象” 的介紹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容