美文网首页
iOS RunLoop(2)-应用

iOS RunLoop(2)-应用

作者: switer_iOS | 来源:发表于2021-06-29 09:23 被阅读0次

    RunLoop在实际开中的应用

    控制线程生命周期(线程保活);
    解决NSTimer在滑动时停止工作的问题;
    监控应用卡顿;
    性能优化;

    1. 解决NSTimer在滑动时停止工作的问题
      static int count = 0;
      // 2.添加到指定模式下
      NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
      NSLog(@"%d", ++count);
      }];
      // [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
      // [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];

    // NSDefaultRunLoopMode、UITrackingRunLoopMode才是真正存在的模式
    // NSRunLoopCommonModes并不是一个真的模式,它只是一个标记
    // timer能在_commonModes数组中存放的模式下工作
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    原因:是runloop只能运行在一种模式下,timer是在默认模式下工作的,不是在UItrackRunloop的模式下工作.

    1. 线程保活
      我们先封装一个长久活命的线程

    \PermanentThread.h
    // 声明一个block - 用于执行任务
    typedef void(^PermanentThreadTask)(void);

    /** 线程保活 */
    @interface PermanentThread : NSObject

    // 在当前线程执行一个任务

    • (void)executeTask:(PermanentThreadTask)task;

    // 结束线程

    • (void)stop;

    @end
    \PermanentThread.m
    /** CSThread **/
    @interface CSThread : NSThread
    @end
    @implementation CSThread

    • (void)dealloc {
      NSLog(@"%s", func);
      }
      @end

    @interface PermanentThread()
    /** 线程/
    @property(nonatomic,strong)CSThread thread;
    /
    是否停止*/
    @property(nonatomic,assign, getter=isStopped)BOOL stopped;
    @end

    @implementation PermanentThread

    // 初始化方法

    • (instancetype)init {
      self = [super init];
      if (self) {
      self.stopped = NO;

        // 初始化线程
        __weak typeof(self) weakSelf = self;
        self.thread = [[CSThread alloc] initWithBlock:^{
            // runloop只有添加事件才会执行
            [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc]init] forMode:NSDefaultRunLoopMode];
            
            // 当当前对象存在并且变量为false的时候,才一直执行
            while (weakSelf && !weakSelf.isStopped) {
                [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
            }
        }];
        
        // 开启线程
        [self.thread start];
      

      }
      return self;
      }

    • (void)dealloc {
      NSLog(@"%s", func);

      [self stop];
      }

    pragma mark - public method

    // 执行任务

    • (void)executeTask:(PermanentThreadTask)task {
      // 如果线程释放或者无任务,则退出
      if (!self.thread || !task) {
      return;
      }

      // 开始执行任务
      //waitUntilDone表示是否等待子线程处理完成后在运行之后的代码.
      [self performSelector:@selector(innerExecuteTask:) onThread:self.thread withObject:task waitUntilDone:NO];
      }

    // 停止

    • (void)stop {
      if (!self.thread) {
      return;
      }

      [self performSelector:@selector(innerStop) onThread:self.thread withObject:nil waitUntilDone:YES];
      }

    pragma mark - private method

    // 执行任务

    • (void)innerExecuteTask:(PermanentThreadTask)task {
      task();
      }

    // 停止线程 runloop

    • (void)innerStop {
      self.stopped = YES;
      CFRunLoopStop(CFRunLoopGetCurrent());
      self.thread = nil;
      }

    @end

    • (void)viewDidLoad {
      [super viewDidLoad];

      // 2.线程保活
      self.thread = [[PermanentThread alloc] init];
      }

    • (void)dealloc {
      NSLog(@"%s", func);
      }

    • (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
      [self.thread executeTask:^{
      NSLog(@"执行任务 - %@", [NSThread currentThread]);
      }];
      }

    • (void)stopBtnClick {
      [self.thread stop];
      }

    相关文章

      网友评论

          本文标题:iOS RunLoop(2)-应用

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