美文网首页
Runloop模式

Runloop模式

作者: 抹不掉那伤1 | 来源:发表于2018-05-24 13:27 被阅读0次

    2018-05-24
    iOS程序的入口是main函数,在main函数里int a = UIApplicationMain之前的代码可以执行,而在其后面的却不能执行。是因为UIApplicationMain里面开启了一个死循环(Runloop 循环)。

    意义

    • 保住当前线程的生命。
    • 监听事件:触摸、时钟、网络、UI等等!
    - (void)viewDidLoad {
        [super viewDidLoad];
        NSTimer * timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(otherMethod) userInfo:nil repeats:YES];
    }
    -(void)otherMethod{
        NSLog(@"OtherMethod --- %@",[NSThread currentThread]);
    }
    

    以上的otherMethod方法并不会执行,timer被释放了,通过在viewDidLoad后面添加下面的代码可以证明。

        __weak typeof(timer) aaaaa = timer;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            if (aaaaa == nil) {
                NSLog(@"释放了");
            }
        });
    

    那么应该如何解决呢?我们将timer添加到Runloop当中添加以下代码

      [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    

    运行后otherMethod开始执行了,timer也不释放了。
    上面说Runloop会监听UI事件,如果在app里添加一给UIScrollView并在运行后滚动它,会发现otherMethod方法停止了调用,停止滚动后就恢复了。这是为什么呢?

    Runloop监听所有事件是分模式的,我的理解就是Runloop将处理的事件分类,当Runloop处在一个模式下就会处理对应的类别的事件。

    • 默认模式NSDefaultRunLoopMode
    • UI模式UITrackingRunLoopMode

    前面将timer添加到Runloop的时候传的参数是NSDefaultRunLoopMode就相当于将timer产生的事件标记为Runloop在默认模式下才会监听的事件,而在滑动UIScrollView时Runloop的UI模式下的Source会产生事件,又因为UI模式的优先级高,Runloop会切换到UI模式(即:默认模式下的timer和UI模式下的Source同时产生事件时,会监听后者),这时otherMethod方法就不会执行了。

    NSDefaultRunLoopMode改为UITrackingRunLoopMode,触摸并滑动UIScrollView后可以发现otherMethod方法开始执行了,松开手后又停止执行了,是因为UI模式只会被触摸事件所触发

    为了让拖拽与否都能处理Timer事件可以这样

    [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    

    将Timer分别添加到两个模式中去,但是苹果有更好的办法,向下面的那样。

    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    

    NSRunLoopCommonModes占位模式,相当于NSDefaultRunLoopModeUITrackingRunLoopMode的两个模式的组合。

    相关文章

      网友评论

          本文标题:Runloop模式

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