iOS知识点总结

iOS Runloop简析

2019-04-26  本文已影响5人  飞不越疯人院

1. 什么是Runloop?

事件循环:没有消息处理时会处于休眠状态避免资源占用(用户态->内核态);有事件处理时会立刻唤醒(内核态->用户态);


2. 为什么main函数能保持不退出?

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

main函数本质上是调用UIApplicationMain函数; 在UIApplicationMain函数内部创建了main runloop, 根据runloop的特点, 它可以不断的接收处理消息, 处理完事件后继续等待; 它就这样一直这样在内核态用户态之间切换循环下去 ; 所以main函数不会被退出;


3. Runloop的各种Mode?

CommonMode不是实际存在的一种Mode;
它是同步Source/Timer/Observer到多个Mode中的一种方案;


Runloop对象可以包含多个Mode, 而每个Mode包含多个timer, observer, 'source';

知识点:如何解决UITableView上轮播图在滚动时失效的问题?
主线程的Mode有两种模式, 默认是NSDefaultRunLoopMode模式, 当滚动tableView时回切换到UITrackingRunLoopMode模式, 这时轮播图的timer就会失效, 将timer添加到NSRunLoopCommonModes可以解决这个问题;

4. 怎样实现一个常驻线程?

 ///创建一个source     这里为什么这样写?
    CFRunLoopSourceContext context = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
    ///当一个runloop中没有事件源处理时, 运行完就会退出;
    CFRunLoopSourceRef source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
    ///1. 2. 创建runloop 同时向runloop中的defaultMode下面添加source
    CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
    ///3. 启动runloop
    while (shouldRun) {
        @autoreleasepool {
            ///令当前的runloop运行在defaultMode下
            CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e20, true);
        }
    }
    ///某个时机, 将静态变量shouldRun = NO时, 退出runloop, 进而退出线程;
    CFRunLoopRemoveSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
    CFRelease(source);

文中示例代码


参考文章
用户态和内核态
iOS UIApplicationMain函数做了什么
iOS 深入理解RunLoop
iOS 简单监测iOS卡顿的demo
iOS 多线程技术之二RunLoop

上一篇下一篇

猜你喜欢

热点阅读