iOS多线程开发(三)---Run Loop(一)
?
Run Loop
Run Loop就是一個(gè)事件處理的循環(huán),用來(lái)不停的調(diào)動(dòng)工作以及處理輸入事件。使用Run Loop的目的就是節(jié)省CPU效率,線程在有工作的時(shí)候忙于工作,而沒(méi)工作的時(shí)候處于休眠狀態(tài)。 一,Run Loop剖析 Structure of a Run Loop and its sources 上圖顯示了線程的輸入源 A,基于端口的輸入源(Port Sources) B,自定義輸入源(Custom Sources) C,Cocoa執(zhí)行Selector的源("performSelector...方法" Sources) D,定時(shí)源(Timer Sources ) 線程針對(duì)上面不同的輸入源,有不同的處理機(jī)制 A,handlePort---處理基于端口的輸入源 B,customSrc---處理用戶自定義輸入源 C,mySelector---處理Selector的源 D,timerFired---處理定時(shí)源 注:線程除了處理輸入源,Run Loops也會(huì)生成關(guān)于Run Loop行為的通知(notification)。Run Loop觀察者(Run-Loop Observers)可以收到這些通知,并在線程上面使用他們來(lái)作額為的處理 ===在新線程的Run Loop中注冊(cè)O(shè)bservers: ---編寫一個(gè)帶有觀測(cè)者的線程加載程序 - (void)observerRunLoop { // 建立自動(dòng)釋放池 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // 獲得當(dāng)前thread的Run loop NSRunLoop *myRunLoop = [NSRunLoop currentRunLoop]; // 設(shè)置Run Loop observer的運(yùn)行環(huán)境 CFRunLoopObserverContext context = {0, self, NULL, NULL, NULL}; // 創(chuàng)建Run loop observer對(duì)象 // 第一個(gè)參數(shù)用于分配該observer對(duì)象的內(nèi)存 //?第二個(gè)參數(shù)用以設(shè)置該observer所要關(guān)注的的事件,詳見(jiàn)回調(diào)函數(shù)myRunLoopObserver中注釋 //?第三個(gè)參數(shù)用于標(biāo)識(shí)該observer是在第一次進(jìn)入run loop時(shí)執(zhí)行還是每次進(jìn)入run loop處理時(shí)均執(zhí)行 //?第四個(gè)參數(shù)用于設(shè)置該observer的優(yōu)先級(jí) //?第五個(gè)參數(shù)用于設(shè)置該observer的回調(diào)函數(shù) //?第六個(gè)參數(shù)用于設(shè)置該observer的運(yùn)行環(huán)境 CFRunLoopObserverRef observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, &myRunLoopObserver, &context); if(observer) { // 將Cocoa的NSRunLoop類型轉(zhuǎn)換程Core Foundation的CFRunLoopRef類型 CFRunLoopRef ? = [myRunLoop getCFRunLoop]; // 將新建的observer加入到當(dāng)前的thread的run loop CFRunLoopAddObserver(cfRunLoop, observer, kCFRunLoopDefaultMode); } // Creates and returns a new NSTimer object and schedules it on the current run loop in the default mode [NSTimer scheduledTimerWithTImeInterval:0.1 target:self selector:@selector(doFireTimer:) userInfor:nil repeats:YES]; NSInteger = loopCount = 10; do { // 啟動(dòng)當(dāng)前thread的run loop直到所指定的時(shí)間到達(dá),在run loop運(yùn)行時(shí),run loop會(huì)處理所有來(lái)自與該run loop聯(lián)系的input sources的數(shù)據(jù) // 對(duì)于本例與當(dāng)前run loop聯(lián)系的input source只有Timer類型的source // 該Timer每隔0.1秒發(fā)送觸發(fā)時(shí)間給run loop,run loop檢測(cè)到該事件時(shí)會(huì)調(diào)用相應(yīng)的處理方法(doFireTimer:) // 由于在run loop添加了observer,且設(shè)置observer對(duì)所有的run loop行為感興趣 // 當(dāng)調(diào)用runUntilDate方法時(shí),observer檢測(cè)到run loop啟動(dòng)并進(jìn)入循環(huán),observer會(huì)調(diào)用其回調(diào)函數(shù),第二個(gè)參數(shù)所傳遞的行為時(shí)kCFRunLoopEntry // observer檢測(cè)到run loop的其他行為并調(diào)用回調(diào)函數(shù)的操作與上面的描述相類似 [myRunLoop runUntilDate:[NSDate dateWithTimeIntervalSiceNow:1.0]]; // 當(dāng)run loop的運(yùn)行時(shí)間到達(dá)時(shí),會(huì)退出當(dāng)前的run loop,observer同樣會(huì)檢測(cè)到run loop的退出行為,并調(diào)用其回調(diào)函數(shù),第二個(gè)參數(shù)傳遞的行為是kCFRunLoopExit. --loopCount; }while(loopCount); //?釋放自動(dòng)釋放池 [pool release]; } ===observer的回調(diào)函數(shù): void myRunLoopObserver(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) { switch(activity) { // The entrance of run loop, before entering the event processing loop. //?This activity occurs once for each call to CFRunLoopRun / CFRunLoopRunInMode case kCFRunLoopEntry: NSLog(@"run loop entry"); break; // Inside the event processing loop before any timers are processed case kCFRunLoopBeforeTimers: NSLog(@"run loop before timers"); break; // Inside the event processing loop before any sources are processed case kCFRunLoopBeforeSources: NSLog(@"run loop before sources"); break; // Inside the event processing loop before the run loop sleeps, waiting for a source or timer to fire // This activity does not occur if CFRunLoopRunInMode is called with a timeout of o seconds // It also does not occur in a particular iteration of the event processing loop if a version 0 source fires case kCFRunLoopBeforeWaiting: NSLog(@"run loop before waiting"); break; //?Inside the event processing loop after the run loop wakes up, but before processing the event that woke it up //?This activity occurs only if the run loop did in fact go to sleep during the current loop case kCFRunLoopAfterWaiting: NSLog(@"run loop after waiting"); break; // The exit of the run loop, after exiting the event processing loop // This activity occurs once for each call to CFRunLoopRun and CFRunLoopRunInMode case kCFRunLoopExit: NSLog(@"run loop exit"); break; /* A combination of all the preceding stages case kCFRunLoopAllActivities: break; */ default: break; } } 1,Run Loop模式---是所有要監(jiān)測(cè)的輸入源和定時(shí)源以及要通知的run loop注冊(cè)觀察者的集合。在run loop運(yùn)行過(guò)程中,只有和模式相關(guān)的源才會(huì)被監(jiān)測(cè)并允許他們傳遞事件消息。相反,沒(méi)有被添加的輸入源將會(huì)被過(guò)濾。 可以自定自己的Run Loop模式,但是每個(gè)模式必須有一個(gè)或者多個(gè)輸入源,定時(shí)源或者run loop的觀察者,否則,run loop直接退出,Run Loop模式將沒(méi)有意義。 另,模式區(qū)分基于事件的源而非事件的種類。例如,不能使用模式只選擇處理鼠標(biāo)按下或者鍵盤事件。可以使用模式監(jiān)聽(tīng)端口,而暫停定時(shí)器或者改變其他源或者當(dāng)前模式下處于監(jiān)聽(tīng)狀態(tài)run loop觀測(cè)著。表1-1列出了cocoa和Core Foundation預(yù)先定義的模式。
2,Run Loop的輸入源? A,基于端口的輸入源 通過(guò)內(nèi)置的端口相關(guān)的對(duì)象和函數(shù),創(chuàng)建配置基于端口的輸入源。相關(guān)的端口函數(shù)---CFMachPort/CFMessagePortRef/CFSocketRf B,自定義輸入源 自定義輸入源使用CFRunLoopSourceRef對(duì)象創(chuàng)建,它需要自定義自己的行為和消息傳遞機(jī)制 C,Cocoa執(zhí)行Selector的源 和基于端口的源一樣,執(zhí)行Selector的請(qǐng)求會(huì)在目標(biāo)線程上序列化,減緩在線程上允許許多各方法容易引起的同步問(wèn)題。兩者區(qū)別:一個(gè)Selector執(zhí)行完成后會(huì)自動(dòng)從Run Loop上移除。Table:Performing selectors on other threads
| Methods | Description |
| performSelectorOnMainThread:withObject: waitUntilDone: performSelectorOnMainThread:withObject: waitUntilDone:modes: | Performs the specified selector on the? application’s main thread during that? thread’s next run loop cycle. These? methods give you the option of blocking? the current thread until the selector is? performed. |
| performSelector:onThread:withObject:waitUntilDone: performSelector:onThread:withObject: waitUntilDone:modes: | Performs the specified selector on any? thread for which you have an?NSThread object. These methods give you the? option of blocking the current thread? until the selector is performed. |
| performSelector:withObject:afterDelay: performSelector:withObject:afterDelay:inModes: | Performs the specified selector on the? current thread during the next run loop? cycle and after an optional delay period.? Because it waits until the next run loop? cycle to perform the selector, these? methods provide an automatic mini? delay from the currently executing code.? Multiple queued selectors are performed? one after another in the order they were? queued. |
| cancelPreviousPerformRequestsWithTarget: cancelPreviousPerformRequestsWithTarget: selector:object: | Lets you cancel a message sent to the? current thread using theperformSelector:withObject:afterDelay: orperformSelector:withObject:afterDelay: inModes:method. |
轉(zhuǎn)載于:https://www.cnblogs.com/luqinbin/p/5154206.html
總結(jié)
以上是生活随笔為你收集整理的iOS多线程开发(三)---Run Loop(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 代码约束2
- 下一篇: mysql sql_safe_updat