RunLoop的知识小记

RunLoop字面上的意思是,运行循环;

其基本作用:保持程序的持续运行;

      处理App中的各种事件(比如:触摸事件、定时器事件、Selector事件)

      节省CPU资源,提高程序性能:该做事时做事,该休息时休息

1.main函数中的RunLoop

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


在这个main函数中,UIApplicationMain函数内部就启动了一个RunLoop,所以UIApplicationMain函数一直没有返回,保持了程序的持续运行。这个默认启动的RunLoop是跟主线程相关联的。

NSRunLoop 是基于CFRunLoopRef的一层OC包装,所以了解RunLoop内部结构,需要多研究CFRunLoopRef层面的API。

2.RunLoop与线程的关系

每条线程都有唯一的一个与之对应的RunLoop对象
主线程的RunLoop已经自动创建好了,子线程的RunLoop需要主动创建
RunLoop在第一次获取时创建,在线程结束时销毁
获取子线程对应的RunLoop(即,currentRunLoop)该方法本身是懒加载的,如果第一次调用就会创建当前线程对应的RunLoop并保存,以后调用则直接获取

3.RunLoop的获取

#pragma mark - RunLoop
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //OC语言中的API
    //01 获取主线程对应的runloop对象
    NSRunLoop *mainRunloop = [NSRunLoop mainRunLoop];
    //02 获取当前的runloop的对象
    NSRunLoop *currentRunloop = [NSRunLoop currentRunLoop];
    NSLog(@"%p---%p", mainRunloop, currentRunloop);
    
    //C语言的API
    //01 主运行循环
    CFRunLoopRef mainRunloopRef = CFRunLoopGetMain();
    //02 当前的运行循环
    CFRunLoopRef currentRunloopRef = CFRunLoopGetCurrent();
    NSLog(@"%p---%p", mainRunloopRef, currentRunloopRef);
    
    //转化
    NSLog(@"%p----%p", mainRunloop.getCFRunLoop, mainRunloopRef);
}

打印的结果:

2019-09-18 15:31:31.176193+0800 NSCach[60622:1117017] 0x60000184c060---0x60000184c060
2019-09-18 15:31:31.176302+0800 NSCach[60622:1117017] 0x600000050600---0x600000050600
2019-09-18 15:31:31.176362+0800 NSCach[60622:1117017] 0x600000050600----0x600000050600

可以看出,当前的主运行循环和当前运行循环是同一个runloop, 最后一行可以看出,OC获取的runloop与C的runloop可以相互转化。

猜你喜欢

转载自www.cnblogs.com/lyz0925/p/11544344.html