美文网首页
iOS及Mac开发 延迟执行处理问题

iOS及Mac开发 延迟执行处理问题

作者: 雨后天_ | 来源:发表于2019-10-23 16:51 被阅读0次

    需求:一组数据指令(1000个),每个模型(比如float time = 30ms)里保存有一个毫秒级的时间。然后执行第一个指令是在0ms,第二个指令是在30ms   第3个指令是在60ms,以此类推。那么执行完全部命令就是30 * 1000 = 30000ms  .

    1,如果你用for循环在里面用 [NSThread sleepForTimeInterval:0.03];是万万不行的。100%大于30s 误差在2s以上

         CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();

        for(inti =0; i <1000; i++) {

            [NSThread sleepForTimeInterval:0.03];

        }

        CFAbsoluteTime linkTime = (CFAbsoluteTimeGetCurrent() - startTime) * 1000;

        NSLog(@"------cost time = %f ms(毫秒)", linkTime);// ------cost time = 30968.497992 ms(毫秒)

    解决办法:

    @property (nonatomic, assign) CFAbsoluteTime startTime;//全局记录开始的时间

    @property (nonatomic, assign) BOOL                stop;//记录是否停止所有延迟 yes 为全部停止

    - (void)test

    {

       dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{//放子线创建延迟

        _startTime = CFAbsoluteTimeGetCurrent();

        floattime =0;//单位s

        for(inti =0; i <1000; i++) {

            [self performSelector:@selector(timeoutMethod:)withObject:@(i)afterDelay:time];

            time = time +0.03;

        }

      if (![NSRunLoop currentRunLoop].currentMode) {//只开启一次

            [[NSRunLoop currentRunLoop] run];

        }

      });

    }

    - (void)timeoutMethod:(NSNumber*)num

    {

        if(self.stop) {

            [NSObject cancelPreviousPerformRequestsWithTarget:self];//停止  一定要在当前线程调用。测试过在子线程创建的延迟,即使是在主线程也取消不了

            return;

        }

    //在这里做你延迟后想做的事情

        if([num isEqual:@(999)]) {//执行最后一条命令打印时间

            CFAbsoluteTime linkTime = (CFAbsoluteTimeGetCurrent() - _startTime) * 1000;

            NSLog(@"Linked in %f ms", linkTime );//Linked in 30004.699974 ms一般误差在10ms左右

        }

    }

    当要某一时刻停止全部任务时用    [NSObject cancelPreviousPerformRequestsWithTarget:self];

    (建议循环创建延迟        [self performSelector:@selector(timeoutMethod:)withObject:@(i)afterDelay:time]; 放在子线程,同时记得要开启runloop,如果放主线程,当你操作UI控件的时候(比如一直拖着tableview不放)timeoutMethod是不执行的,需要你放了拖拽tableview才会继续执行timeoutMethod延迟方法,当然把主线程的runloop改为在CommonMode,可以解决这种问题。

    相关文章

      网友评论

          本文标题:iOS及Mac开发 延迟执行处理问题

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