美文网首页
iOS RunLoop总结

iOS RunLoop总结

作者: Shirly_you | 来源:发表于2017-06-22 15:57 被阅读0次
    一.RunLoop的基本概念

    RunLoop是oc底层的一个机制,是运行循环,死循环。当应用程序需要的时候跑起来,不需要的时候处于休眠状态,这种特性可以充分提高CPU资源,提高程序的性能。

    NSRunLoop三种模式:

    1. NSRunLoopCommonModes:占位模式(并不是runloop的一种模式) 无论是否操作UI都处理timer事件
    2. NSDefaultRunLoopMode:默认模式 当不操作UI的时候才 苹果建议处理timer事件 网络事件
    3. UITrackingRunLoopMode:ui 模式 当操作ui的时候才处理timer事件 苹果建议处理ui事件
    二.RunLoop的作用

    RunLoop常常和线程结合在一起讨论

    1.保证线程不退出(RunLoop一旦启动 线程就不会退出)

    一般来讲,一个线程一次只能执行一个任务,执行完成后线程就会退出。但是有时候我们需要线程能够一直“待命”随时处理事件而不退出,这就需要一个机制来完成这样的任务。

    2.负责监听所有的事件 iOS中的触摸/时钟/网络事件

    比如说时钟事件 创建timer 有两种方式 一种是

    (1). 添加到默认模式 将RunLoop封装起来

    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
    

    (2).另一种是创建timer后手动开启runloop

    _finished = NO;
    _tasks = [NSMutableArray array];
    //创建的子线程
          NSThread *thread = [[NSThread alloc] initWithBlock:^{
          NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
    //将timer加到当前runloop中 但是执行一次后 线程被释放
          [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    //让当前线程的runloop跑起来 监听事件 保证线程不被释放 如果没有这段代码 则执行一次后线程会被释放 一条线程要想保住 必须让runloop启动 是一个死循环
          [[NSRunLoop currentRunLoop] run];
        while (!_finished) {
    //让runloop跑0.00001秒 跑起来有事情处理事情 没事情就沉睡
            [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.0001]];
        }
    //有[[NSRunLoop currentRunLoop] run];则不会打印
         NSLog(@"我来了");
    }];
    //启动线程
        [thread start];
    //强引用使thread对象不会被释放 保住的是thread(一个oc对象) 但没有保住线程 线程是由CPU来调用的和oc对象没有丝毫关系 oc对象只是提供了一个接口来操作线程 线程的释放与oc没关系 只能runloop来保住线程
         self.thread = thread;
    

    在这里如果不手动开启runloop 即[[NSRunLoop currentRunLoop] run]则线程执行一次后就直接被释放 如果声明一个强引用只能使thread对象不会被释放 保住的是thread(一个oc对象) 但没有保住线程 线程是由CPU来调用的和oc对象没有丝毫关系 oc对象只是提供了一个接口来操作线程 线程的释放与oc没关系 只能runloop来保住线程。

    3.负责绘制UI
    三.RunLoop与线程的关系

    RunLoop,最重要的作用,也就是用来管理线程的。可以说,没有线程,也就没有RunLoop的存在必要。

    主线程和子线程:

    1.没有任何分别
    2.只不过主线程的RunLoop是由操作系统来开启的 子线程的RunLoop是由开发者手动开启的。
    其实在我们每次建立项目的时候,就已经使用上了RunLoop。
    在程序的启动入口main函数中有这样一段熟悉的代码:

    参数解释:
            argc, argv:则是由操作系统传给app的所以这两个参数无需管理
            nil:默认是字符串@“UIApplication” 当然也可以自定义一个类继承UIApplication 
            NSStringFromClass([AppDelegate class]:字符串 
            应用程序的main函数是由操作系统启动的,操作系统开启了一条主线程(对应用程序来说是主线程 但对于操作系统来说是子线程)此内部已经开启了RunLoop死循环,所以app的主线程是常驻线程,在自动释放池中不会被释放从而保证应用程序不会退出。
    
    int main(int argc, char * argv[]) {
        @autoreleasepool {
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
    }
    

    相关文章

      网友评论

          本文标题:iOS RunLoop总结

          本文链接:https://www.haomeiwen.com/subject/vetfcxtx.html