当前位置: 首页 > 编程笔记 >

IOS开发中延迟执行和取消

田瀚
2023-03-14
本文向大家介绍IOS开发中延迟执行和取消,包括了IOS开发中延迟执行和取消的使用技巧和注意事项,需要的朋友参考一下

在 Objective-C 中延迟执行还是很常见的需求,通常有如下几种方式可供选择:

performSelector:

想要延迟调用某个方法:

[self performSelector:@selector(delay) withObject:nil afterDelay:3.0];

取消延迟的方法:

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(delay) html" target="_blank">object:nil];

这里需要注意参数需要保持一致,否则取消失败。

NSTimer

想要延迟调用某个方法:

self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(delay) userInfo:nil repeats:NO];

取消延迟的方法:

[self.timer invalidate];
GCD

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    // ...
});

dispatch_after 是比较常用的方法,但是 Objective-C 中并没有提供取消执行的相关 API。我们只能自己实现这个取消的逻辑:

typedef void (^Task)(BOOL cancel);
Task delay(NSTimeInterval time,void (^task)()) {
  __block void (^closure)() = task;
  __block Task result;
  Task delayedClosure = ^(BOOL cancel){
    if (closure) {
      void (^internalClosure)() = closure;
      if (!cancel) {
        dispatch_async(dispatch_get_main_queue(), internalClosure);
      }
    }
    closure = nil;
    result = nil;
  };
  
  result = delayedClosure;
  
  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(time * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    if (delayedClosure) {
      delayedClosure(NO);
    }
  });
  return result;
}
使用的话可以这样:

delay(60, ^{
  // ...
});

如果想要延迟,可以先声明成成员变量并赋值:

@property (copy, nonatomic) Task task;
self.task = delay(60, ^{
  // ...
});

最后在需要的地方取消就行:

self.task(YES);

这种写法的核心思想是根据传入的 Bool 值,来控制 dispatch_after 回调 block 中的方法是否需要执行。看起来是取消了,但实际上还是被 GCD 放到 RunLoop 里去占用主线程资源了。

dispatch_source

我们还可以利用 dispatch_source 中的定时器,来实现延时/取消操作:

@property (strong, nonatomic) dispatch_source_t timer;
// 队列
dispatch_queue_t queue = dispatch_get_main_queue();
// 创建 dispatch_source
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
// 声明成员变量
self.timer = timer;
// 设置两秒后触发
dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, 3.0 * NSEC_PER_SEC);
// 设置下次触发事件为 DISPATCH_TIME_FOREVER
dispatch_time_t nextTime = DISPATCH_TIME_FOREVER;
// 设置精确度
dispatch_time_t leeway = 0.1 * NSEC_PER_SEC;
// 配置时间
dispatch_source_set_timer(timer, startTime, nextTime, leeway);
// 回调
dispatch_source_set_event_handler(timer, ^{
  // ...
});
// 激活
dispatch_resume(timer);

需要取消的话:

dispatch_source_cancel(self.timer);

 类似资料:
  • 本文向大家介绍iOS延迟执行方法详解,包括了iOS延迟执行方法详解的使用技巧和注意事项,需要的朋友参考一下 近日学习了延迟执行的几种方法,分享一下。 1.performSelector(NSObject)方法  2.NSTimer方法  3.GCD方法  4.sleep(NSThread)方法 延迟执行代码: 1.performSelector(NSObject)方法 这是iOS中常用的一种延迟执

  • 最初,我在运行拓扑时只分配了1个executor给QueryNormalizer。执行潜伏期为8.952,处理潜伏期为12.857。 为了更快,我将QueryNormalizer中的执行程序数更改为4。执行延迟更改为197.616,处理延迟更改为59.132。 根据执行延迟的定义-元组在执行方法中花费的平均时间。execute方法可以在不发送元组的Ack的情况下完成。 此外,处理延迟是否应始终低于

  • 问题内容: 运行上面的代码后,未执行,我的意思是文本字段未将其文本设置为“ START”, 为什么? 如何解决呢? 问题答案: 请记住,该按钮在JavaFX线程上被调用,因此您实际上将UI线程暂停了5秒钟。在这五秒钟的末尾取消冻结UI线程时,将同时应用这两个更改,因此最终只能看到第二个。 您可以通过在新线程中运行以上所有代码来解决此问题:

  • 当我像这样定义和调用客户机方法时: 关于更多上下文:在我的例子中,我只希望在CacheFlux onCacheMissResume被触发时执行它:

  • 我把来自https://bitnami.com/stack/cassandra的卡珊德拉安装在云机器上。我克隆了这台机器,所以我有2台机器。一个运行cassandra服务器(1节点cassandra集群),另一个充当客户端并向第一个服务器发出查询。 我使用YCSB-https://github.com/brianfrankcooper/YCSB来执行基准测试。我观察到服务器上的读取延迟非常低,只有

  • 本文向大家介绍对比分析iOS延迟执行的4种方式,包括了对比分析iOS延迟执行的4种方式的使用技巧和注意事项,需要的朋友参考一下 最近学习了延迟执行的几种方法,分享一下: 1.performSelector(NSObject)方法  2.NSTimer方法  3.GCD方法  4.sleep(NSThread)方法 一、performSelector方法: 1.特点: 此方式要求必须在主线程中执行,