runloop

作者: DL是谁 | 来源:发表于2019-05-07 17:32 被阅读0次

    通过内部维护的事件循环来对事件或者消息进行管理的一个对象
    不要说运行循环,说是用户态到内核态,内核态到用户态的转

    1)'kCFRunLoopDefaultMode':App的默认Mode,通常主线程是在这个Mode下运行
    2)'UITrackingRunLoopMode':界面跟踪 Mode,用于 ScrollView追踪触摸滑动,保证界面滑动时不受其他Mode 影响
    3)'UIInitializationRunLoopMode': 在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用
    4)'GSEventReceiveRunLoopMode': 接受系统事件的内部 Mode,通常用不到
    5)'kCFRunLoopCommonModes': 这是一个占位用的Mode,不是一种真正的Mode

    /*
    CommonMode并不是一种实际的模式,和defaultmode完全不是一回事。简单的理解就是,如果设置了CommonMode模式,那么runloop在切换mode的同时,也把timer的事件也带走了,所以无论切到哪种mode下,timer的事件都是可以处理的。
    */

    Q:滑动tableView的时候,timer事件的轮播器不走了。
    分析: 到底是什么原因。
    解决办法:大家都知道,timer的mode从defaultmode,换到CommonMode就可以了。

    问题:为什么为什么就可以了。
    回答tableView滚动timer不走问题:
    1.默认滚动事件和timer事件都是在kCFRunloopDefaultMode下的
    2.此时tableView一滚动,mode切换到UITrackingRunloopMode中,上面说,runloop同一时间只能处理一种mode的事件,那么在DefaultMode的timer就无法响应了。
    3.CommonMode又是一个同步多种mode的技术方案,此模式下,当runloop到UITrackingRunloopMode的时候,他把timer的事件也转移到UITrackingRunloopMode下,那么timer就能走了。

    常驻线程

    • (NSThread *)networkRequestThread {
      static NSThread *_networkRequestThread = nil;
      static dispatch_once_t oncePredicate;
      dispatch_once(&oncePredicate, ^{
      _networkRequestThread = [[NSThread alloc] initWithTarget:self selector:@selector(networkRequestThreadEntryPoint:) object:nil];
      [_networkRequestThread start];
      });
      return _networkRequestThread;
      }

    • (void)networkRequestThreadEntryPoint:(id)__unused object {
      @autoreleasepool {
      [[NSThread currentThread] setName:@"AFNetworking"];
      NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
      [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
      [runLoop run];
      }
      }

    移除常驻线程方法
    /// 停止常驻线程
    {
    self.stopLoopRunning = YES;

        // 移除 port
        // 如果是用 timer 的方式的常驻线程, 可以 invalid 对应的 timer
        [self.threadRunLoop removePort:self.threadPort forMode:NSRunLoopCommonModes];
        
        // 停止 RunLoop
        if (nil != self.threadRunLoop) {
            CFRunLoopStop([self.threadRunLoop getCFRunLoop]);
        }
    }
    

    http://www.veryitman.com/2018/07/01/RunLoop-移除常驻线程/
    https://blog.csdn.net/u014795020/article/details/72084735
    https://blog.csdn.net/xiaoxiaobukuang/article/details/80021616

    相关文章

      网友评论

          本文标题:runloop

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