iOS開發RunLoop學習:三:Runloop相關類(source和Observer)


 

一:RunLoop相關類:

其中:source0指的是非基於端口por,說白了也就是處理觸摸事件,selector事件,source1指的是基於端口的port:是處理系統的一些事件

 

 

注意:創建一個RunLoop之后,有默認的運行模式mode,也可以為RunLoop指定運行模式,RunLoop啟動必須得有運行模式,而且在運行模式中必須還有timer或是source事件其中之一,否則RunLoop就會退出。啟動RunLoop必須調用start方法

 

二:RunLoop運行處理邏輯

 

 RunLoop通知觀察者Observer即將進入RunLoop,此時通知觀察者Observer處理Timer,通知觀察者Observer處理source0(非基於端口port,也就是觸摸,滾動,selector選擇器事件),此時RunLoop會處理source0事件,當處理完source0事件后,如果此時沒有source1(系統事件)則RunLoop進入休眠狀態,直到外部的source0,timer或是外部手動喚醒RunLoop,若是此時有source1事件,則會處理喚醒時受到的消息,之后再繼續跳回2--處理timer--處理source0--在檢查有無source1 ,RunLoop就是一個死循環,最后如果線程被掛掉(也就是線程中的任務執行完畢后,線程就會掛掉,即使使用外部強引用指向該線程,線程依然會掛掉,若是想使線程執行完任務后,不被掛掉,則可以手動開啟RunLoop,為RunLoop指定運行模式mode,在mode中必須為RunLoop指定source或是timer,否則RunLoop會立即退出,)會通知Observer即將退出RunLoop

 

2:蘋果官方版

#import "ViewController.h"

/**
 *    1:為RunLoop添加監聽者:1:先創建監聽者  2:添加監聽者
 */

@interface ViewController ()
/** 注釋 */
//@property (nonatomic, strong) pthread_t thread;
@end

@implementation ViewController

#pragma mark ----------------------
#pragma mark Events
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//    [self observer];
//    [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(task) userInfo:nil repeats:YES];
    
    [NSThread detachNewThreadSelector:@selector(task) toTarget:self withObject:nil];
}

- (IBAction)sourceBtnClick:(id)sender
{
    NSLog(@"%s",__func__);
}

#pragma mark ----------------------
#pragma mark
-(void)task
{
    NSLog(@"%s",__func__);
    
//    [NSRunLoop currentRunLoop] runUntilDate:[];
}

-(void)observer
{
    //1.創建監聽者
    /*
     第一個參數:怎么分配存儲空間
     第二個參數:要監聽的狀態 kCFRunLoopAllActivities 所有的狀態
     第三個參數:時候持續監聽
     第四個參數:優先級 總是傳0
     第五個參數:當狀態改變時候的回調
     */
    CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
        
        /*
         kCFRunLoopEntry = (1UL << 0),        即將進入runloop
         kCFRunLoopBeforeTimers = (1UL << 1), 即將處理timer事件
         kCFRunLoopBeforeSources = (1UL << 2),即將處理source事件
         kCFRunLoopBeforeWaiting = (1UL << 5),即將進入睡眠
         kCFRunLoopAfterWaiting = (1UL << 6), 被喚醒
         kCFRunLoopExit = (1UL << 7),         runloop退出
         kCFRunLoopAllActivities = 0x0FFFFFFFU
         */
        switch (activity) {
            case kCFRunLoopEntry:
                NSLog(@"即將進入runloop");
                break;
            case kCFRunLoopBeforeTimers:
                NSLog(@"即將處理timer事件");
                break;
            case kCFRunLoopBeforeSources:
                NSLog(@"即將處理source事件");
                break;
            case kCFRunLoopBeforeWaiting:
                NSLog(@"即將進入睡眠");
                break;
            case kCFRunLoopAfterWaiting:
                NSLog(@"被喚醒");
                break;
            case kCFRunLoopExit:
                NSLog(@"runloop退出");
                break;
                
            default:
                break;
        }
    });
    
    /*
     第一個參數:要監聽哪個runloop
     第二個參數:觀察者
     第三個參數:運行模式
     */
    CFRunLoopAddObserver(CFRunLoopGetCurrent(),observer, kCFRunLoopDefaultMode);
    
    //NSDefaultRunLoopMode == kCFRunLoopDefaultMode
    //NSRunLoopCommonModes == kCFRunLoopCommonModes
}

@end

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM