iOS开发程序员iOS学习笔记

RunLoop

2017-02-22  本文已影响82人  印林泉
  • RunLoop简单概述

RunLoop简单概述

int main(int argc, char * argv[]) {
    NSLog(@"execute main function");//程序开始
    return 0;//程序结束
}

类似OC程序,执行完相应的代码之后,程序杀死,不能保证APP的持续运行

int main(int argc, char * argv[]) {
    do {
      NSLog(@"execute main function");//程序开始
    } while(1);
    return 0;//程序结束
}

相当于程序内部有一个死循汗,保证程序运行不会中断

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

在UIApplicationMain函数内部就启动了一个RunLoop,所以UIApplicationMain函数就一直没有返回,保持了程序的持续运行

注意:默认启动的RunLoop是跟主线程相关联的,主要处理与主线程相关的事件

NSRunLoop和CFRunLoopRef都是代表RunLoop,其间的联系是NSRunLoop是基于CFRunLoopRef的。也就是说要研究RunLoop的话,还是需要研究CFRunLoopRef

注意:苹果不允许创建RunLoop,只提供上述两种获得RunLoop的方法


RunLoop相关类

若没有以上几个类,RunLoop是不会循环的


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self timer];
}

- (void)timer {
    //自动加在RunLoop下,可以直接运行
    //[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    //只适用默认模式下
    //[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    
    //滑动
    //[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
    
    //CommonModes 只是一个标记
    //有这个标记的模式有NSDefaultRunLoopMode UITrackingRunLoopMode
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}

- (void)run {
    NSLog(@"===run===");
}


typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
    kCFRunLoopEntry = (1UL << 0),//即将进入RunLoop
    kCFRunLoopBeforeTimers = (1UL << 1),//即将进入Timer
    kCFRunLoopBeforeSources = (1UL << 2),//即将处理Sources
    kCFRunLoopBeforeWaiting = (1UL << 5),//即将进入休眠
    kCFRunLoopAfterWaiting = (1UL << 6),//即将从休眠中唤醒
    kCFRunLoopExit = (1UL << 7),//即将退出RunLoop
    kCFRunLoopAllActivities = 0x0FFFFFFFU//活跃中
};

- (void)observer {
    //[self addObserver:<#(nonnull NSObject *)#> forKeyPath:<#(nonnull NSString *)#> options:<#(NSKeyValueObservingOptions)#> context:<#(nullable void *)#>];
    //如果给RunLoop添加观察者 需要CF类
    CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
        NSLog(@"===%lu===", activity);
    });
    CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);
}

RunLoop逻辑处理

RunLoop的处理逻辑.png RunLoop的结构.png

图片来源


- (void)performSelector {
    [self performSelector:@selector(run) withObject:nil afterDelay:2.0 inModes:@[NSRunLoopCommonModes]];
}
上一篇 下一篇

猜你喜欢

热点阅读