一: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
时间: 2024-10-06 08:50:43