iphone——使用run loop對象

來源:互聯網
上載者:User

        如果你在非main thread中運行run loop,你必須至少為該run loop添加一個input sources或timer。如果你啟動並執行run loop沒有監控任何的輸入源,該run loop將在你運行後立即退出。

Run loop observer

        使用detachNewThreadSelector:toTarget:withObject:建立一個thread:

[NSThread detachNewThreadSelector:@selector(observerRunLoop) toTarget:self withObject:nil];

        在新thread的run loop中添加observer:

- (void)observerRunLoop {    //建立自動釋放池    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];        //獲得當前thread的Run loop    NSRunLoop *myRunLoop = [NSRunLoop currentRunLoop];        //設定Run loop observer的運行環境    CFRunLoopObserverContext context = {0, self, NULL, NULL, NULL};        //建立Run loop observer對象    //第一個參數用於分配observer對象的記憶體    //第二個參數用以設定observer所要關注的事件,詳見回呼函數myRunLoopObserver中注釋    //第三個參數用於標識該observer是在第一次進入run loop時執行還是每次進入run loop處理時均執行    //第四個參數用於設定該observer的優先順序    //第五個參數用於設定該observer的回呼函數    //第六個參數用於設定該observer的運行環境    CFRunLoopObserverRef observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, &myRunLoopObserver, &context);            if (observer) {        //將Cocoa的NSRunLoop類型轉換成Core Foundation的CFRunLoopRef類型        CFRunLoopRef cfRunLoop = [myRunLoop getCFRunLoop];        //將建立的observer加入到當前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:) userInfo:nil repeats:YES];        NSInteger loopCount = 10;        do {        //啟動當前thread的loop直到所指定的時間到達,在loop運行時,run loop會處理所有來自與該run loop聯絡的input source的資料        //對於本例與當前run loop聯絡的input source只有一個Timer類型的source。        //該Timer每隔0.1秒發送觸發事件給run loop,run loop檢測到該事件時會調用相應的處理方法。                //由於在run loop添加了observer且設定observer對所有的run loop行為都感興趣。        //當調用runUnitDate方法時,observer檢測到run loop啟動並進入迴圈,observer會調用其回呼函數,第二個參數所傳遞的行為是kCFRunLoopEntry。        //observer檢測到run loop的其它行為並調用回呼函數的操作與上面的描述相類似。        [myRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];        //當run loop的已耗用時間到達時,會退出當前的run loop。observer同樣會檢測到run loop的退出行為並調用其回呼函數,第二個參數所傳遞的行為是kCFRunLoopExit。                loopCount--;    } while (loopCount);        //釋放自動釋放池    [pool release];}

        設定observer的回呼函數:

void myRunLoopObserver(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {    switch (activity) {        //The entrance of the run loop, before entering the event processing loop.         //This activity occurs once for each call to CFRunLoopRun and 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 0 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;    }}

啟動run loop

        啟動run loop的方法:無條件啟動,設定時間限制啟動,在特殊的模式下啟動。

        以無條件模式進入run loop是最簡單的選擇,但並不是最好的選擇。以無條件的形式運行run loop將使thread進入一個永久的迴圈,這樣的操作會使使用者很難對run loop進行控制。你可以為該run loop添加input source或timer,但能退出該run loop的方法就是kill。這種啟動情況下並不能讓run loop運行於自訂模式中。

        不同於無條件方式運行run loop,使用時間限制的方式啟動run loop更好。當你使用逾時時間來對run loop的運行加以限制,則run loop一直運行直至事件到達或達到逾時時間。如果是事件到達,run loop將事件分發給handler(處理器)進行處理並在處理完成後退出。你的代碼然後重啟run loop來處理下一個事件。如果是因到達逾時時間而退出,you can simply restart
the run loop or use the time to do any needed housekeeping。

       除了逾時時間,你還可以運行run loop在特定的模式下。模式和逾時時間並不互斥,你可以在啟動一個run loop時同時指定逾時時間和模式。模式限制了投遞事件給run loop的sources的類型,詳細的見“iphone——NSRunLoop概念”。

退出run loop

        退出run loop的方法:以逾時時間配置run loop啟動,顯式的停止run loop(調用CFRunLoopStop函數)。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.