日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

iOS多线程开发(三)---Run Loop(一)

發(fā)布時(shí)間:2025/3/13 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS多线程开发(三)---Run Loop(一) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

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.

D,定時(shí)源 在預(yù)設(shè)的時(shí)間點(diǎn)同步方式傳遞消息,定時(shí)器是線程通知自己做某事的一種方法。 E,Run Loop觀察者 源是合適的同步/異步事件發(fā)生時(shí)觸發(fā)。觀察者則是在Run Loop本身運(yùn)行的特定時(shí)候觸發(fā)。觀察者觸發(fā)的相關(guān)事件(參考上面紅色程序里面的函數(shù):myRunLoopObserves(...)) 1)Run Loop入口 2)Run Loop何時(shí)處理一個(gè)定時(shí)器 3)Run Loop何時(shí)處理一個(gè)輸入源 4)Run Loop何時(shí)進(jìn)入休眠狀態(tài) 5)Run Loop何時(shí)被喚醒,但在喚醒之前要處理的事件 6)Run Loop終止 注: 1,觀察者通過(guò)CFRunLoopObserverRef對(duì)象創(chuàng)建的 2,觀察者會(huì)在相應(yīng)事件發(fā)生之前傳遞消息,所以通知的時(shí)間和事件實(shí)際發(fā)生的時(shí)間之間肯定有誤差 F,Run Loop 的事件隊(duì)列--包括觀察者的事件隊(duì)列 1)通知觀察者Run Loop已經(jīng)啟動(dòng) 2)通知觀察者任何即將要開(kāi)始的定時(shí)器 3)通知觀察者任何即將啟動(dòng)的非基于端口的輸入源 4)啟動(dòng)任何準(zhǔn)備好的非基于端口的源 5)如果基于端口的源準(zhǔn)備好了并處于等待狀態(tài),立即啟動(dòng);并進(jìn)入步驟9 6)通知觀察者線程進(jìn)入休眠 7)將線程置于休眠直到下面任一事件發(fā)生 A)某一事件到達(dá)基于端口的源 B)定時(shí)器啟動(dòng) C)Run Loop設(shè)置的時(shí)間已經(jīng)超時(shí) D)Run Loop被顯式喚醒 8)通知觀察者線程被喚醒 9)處理未處理的事件 A)如果用戶定義的定時(shí)器啟動(dòng),處理定時(shí)器事件并重啟Run Loop,進(jìn)入步驟2 B)如果輸入源啟動(dòng),傳遞相應(yīng)消息 C)如果Run Loop被顯式喚醒而且時(shí)間還沒(méi)有超時(shí),重啟Run Loop,進(jìn)入步驟2 10)通知觀察者Run Loop結(jié)束

轉(zhuǎn)載于:https://www.cnblogs.com/luqinbin/p/5154206.html

總結(jié)

以上是生活随笔為你收集整理的iOS多线程开发(三)---Run Loop(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。