如何将方法调用延迟 1 秒?

Posted

技术标签:

【中文标题】如何将方法调用延迟 1 秒?【英文标题】:How can I delay a method call for 1 second? 【发布时间】:2010-10-29 13:44:10 【问题描述】:

有没有简单的方法将方法调用延迟 1 秒?

我有一个UIImageView,它对触摸事件做出反应。当检测到触摸时,应用程序中会出现一些动画。一秒钟后,我想调用另一个方法。在这种情况下,我不能使用animationDidStop 选择器。

【问题讨论】:

当然有几种方法可以做到这一点,其中一种可能是简单地使用 sleep() 将程序/线程挂起几毫秒,但是我认为您可能想告诉我们您到底想通过这样做来完成什么?我的意思是,你的实际问题是什么?延迟方法调用的想法似乎是一种“解决方案”,说实话听起来不太好。所以,请告诉我们更多关于您的想法的情况。 【参考方案1】:

Swift 2.x

let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
 dispatch_after(delayTime, dispatch_get_main_queue()) 
 print("do some work")

Swift 3.x --&-- Swift 4

DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) 
    print("do some work")

或传递escaping closure

func delay(seconds: Double, completion: @escaping()-> Void) 
    DispatchQueue.main.asyncAfter(deadline: .now() + seconds, execute: completion)

【讨论】:

【参考方案2】:

在 Swift 3 中使用

perform(<Selector>, with: <object>, afterDelay: <Time in Seconds>)

【讨论】:

【参考方案3】:

你也可以使用块

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^
    [object method]; 
);

大多数情况下,您会希望使用 dispatch_get_main_queue,但如果方法中没有 UI,您可以使用 global queue。

编辑:

Swift 3 版本:

DispatchQueue.main.asyncAfter(deadline: .now() + 1) 
    object.method()

同样,DispatchQueue.global().asyncAfter(... 也可能是一个不错的选择。

【讨论】:

发现这个解决方案在混合直接 C 和 ObjC 时比 performSelector 更容易 不幸的是 dispatch_get_current_queue 自 ios6 以来已被弃用 更新为使用 dispatch_get_main_queue 而不是 dispatch_get_current_queue Xcode 现在会自动完成这个,只需开始输入dispatch_after 并按回车键 特别是现在 Xcode 在输入 dispatch_after 时会自动完成这个,这确实是一种超级简单的方法,而且您可以将属性传递给您正在调用的方法,这很棒。跨度> 【参考方案4】:

已检查的解决方案中有一个 Swift 3 解决方案:

self.perform(#selector(self.targetMethod), with: self, afterDelay: 1.0)

还有方法

@objc fileprivate func targetMethod()


【讨论】:

【参考方案5】:

注意:这将暂停您的整个线程,而不仅仅是一种方法。 在调用您的方法之前调用 sleep/wait/halt 1000 ms?

Sleep(1000); // does nothing the next 1000 mSek

Methodcall(params); // now do the real thing

编辑:上述答案适用于一般问题“如何将方法调用延迟 1 秒?”,这是在回答时提出的问题(实际上答案是在原始问题的 7 分钟内给出的题 :-))。 当时没有提供有关该语言的信息,所以请不要再抱怨使用睡眠 i XCode og 缺少类的正确方法......

【讨论】:

只在当前线程中,其他线程会继续运行。 天啊。我明白为什么这被否决了几次,但到底是谁在 -27 看到了这个并决定需要另一个?是否 -3 或其他东西没有说明问题。为什么不直接编辑答案说“这将暂停你的整个线程”或其他内容,而不是对人们投反对票? 如果你只想暂停整个线程怎么办?如果它带有一个体面的警告,这似乎是一个有效的选择。 @AlbertRenshaw 我完全同意你的看法。我在这里和它的 35 次起伏,我放弃了他。我看到更像是对低声誉用户进行如此严重的攻击。没有人会做任何编辑或指定任何东西。我今天看到一个答案是真的淹死了。该人所做的唯一错误是他/她用客观的 c 语言在一个快速的问题下回答。如果这是一个巨大的错误,我想在客观 c 问题下显示这么多快速的答案。【参考方案6】:

最好的办法是:

[self performSelector:@selector(YourFunctionName) 
           withObject:(can be Self or Object from other Classes) 
           afterDelay:(Time Of Delay)];

您也可以将 nil 作为 withObject 参数传递。

例子:

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

【讨论】:

你为什么要把self传给self? 为什么要将变量传递给采用零参数的方法?【参考方案7】:

已经有很多答案,而且都是正确的。如果您想使用dispatch_after,您应该寻找包含在右下角Code Snippet Library 内的sn-p(您可以在其中选择UI 元素)。

所以你只需要通过在代码中编写dispatch来调用这个sn-p:

【讨论】:

【参考方案8】:

你可以这样做

[self performSelector:@selector(MethodToExecute) withObject:nil afterDelay:1.0 ];

【讨论】:

【参考方案9】:
performSelector:withObject:afterDelay:

Document Reference

【讨论】:

这是正确答案。请看developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/…: 有什么方法可以处理被调用方法的返回值吗?或者如果我想从中获取一些信息,是否需要设置它来修改参数? 如果有人有兴趣如何取消预定的通话:[NSObject cancelPreviousPerformRequestsWithTarget:yourTarget selector:aSelector object: anArgument];【参考方案10】:

您还可以:

[UIView animateWithDuration:1.0
                 animations:^ self.view.alpha = 1.1; /* Some fake chages */ 
                 completion:^(BOOL finished)

    NSLog(@"A second lapsed.");
];

在这种情况下,您必须对某些视图进行一些更改才能使动画正常工作。它确实很hacky,但我喜欢基于块的东西。或者在下面总结@mcfedr 的答案。


waitFor(1.0, ^

    NSLog(@"A second lapsed");
);

typedef void (^WaitCompletionBlock)();
void waitFor(NSTimeInterval duration, WaitCompletionBlock completion)

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC),
                   dispatch_get_main_queue(), ^
     completion(); );

【讨论】:

不确定,但我认为您建议的第一个选项可能具有用户应该注意的副作用,例如阻止用户在部分 UI 上进行交互。我的直觉是它也会导致一些不必要的 CPU 或其他资源消耗,但我没有检查。【参考方案11】:

您可以在调用 0.1 秒延迟方法之后使用执行选择器来执行以下代码。

[self performSelector:@selector(InsertView)  withObject:nil afterDelay:0.1]; 

【讨论】:

以上是关于如何将方法调用延迟 1 秒?的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin延迟后如何调用函数?

如何在两个计时器之间创建延迟?

延迟方法调用[重复]

延迟后调用方法?

unity3d中的怎么实现update的延迟调用

api调用Nodejs之间的延迟