首页 > 代码库 > iOS开发RunLoop学习:三:Runloop相关类(source和Observer)

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

 

iOS开发RunLoop学习:三:Runloop相关类(source和Observer)