let delay = 2.0
let delayInNanoSeconds = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
let mainQueue = dispatch_get_main_queue()
dispatch_after(delayInNanoSeconds, mainQueue, {
print("Some UI related task after delay")
})
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(<#delayInSeconds#> * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), {
<#code to be executed after a specified delay#>
})
// Create custom class, this will make your life easier
class CustomDelay {
static let cd = CustomDelay()
// This is your custom delay function
func runAfterDelay(_ delay:Double, closure:@escaping ()->()) {
let when = DispatchTime.now() + delay
DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}
}
// here how to use it (Example 1)
class YourViewController: UIViewController {
// example delay time 2 second
let delayTime = 2.0
override func viewDidLoad() {
super.viewDidLoad()
CustomDelay.cd.runAfterDelay(delayTime) {
// This func will run after 2 second
// Update your UI here, u don't need to worry to bring this to the main thread because your CustomDelay already make this to main thread automatically :)
self.runFunc()
}
}
// example function 1
func runFunc() {
// do your method 1 here
}
}
// here how to use it (Example 2)
class YourSecondViewController: UIViewController {
// let say you want to user run function shoot after 3 second they tap a button
// Create a button (This is programatically, you can create with storyboard too)
let shootButton: UIButton = {
let button = UIButton(type: .system)
button.frame = CGRect(x: 15, y: 15, width: 40, height: 40) // Customize where do you want to put your button inside your ui
button.setTitle("Shoot", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
// create an action selector when user tap shoot button
shootButton.addTarget(self, action: #selector(shoot), for: .touchUpInside)
}
// example shoot function
func shoot() {
// example delay time 3 second then shoot
let delayTime = 3.0
// delay a shoot after 3 second
CustomDelay.cd.runAfterDelay(delayTime) {
// your shoot method here
// Update your UI here, u don't need to worry to bring this to the main thread because your CustomDelay already make this to main thread automatically :)
}
}
}
17 回答
我相信作者不会问如何等待一个小数时间(延迟),而是如何传递一个标量作为选择器的参数(withObject :)和现代目标C中最快的方法是:
您的选择器必须将其参数更改为NSNumber,并使用floatValue或doubleValue等选择器检索该值
dispatch_after函数在给定的时间段之后将块对象调度到调度队列 . 使用以下代码在2.0秒后执行一些与UI相关的操作 .
在swift 3.0中:
对于Swift,我使用
dispatch_after
方法创建了一个全局函数,没什么特别的 . 我更喜欢这个,因为它易读且易于使用:您可以使用以下内容:
这是我的2美分= 5种方法;)
我喜欢封装这些细节,并让AppCode告诉我如何完成我的句子 .
如何使用Xcode内置代码片段库?
Update for Swift:
很多投票激励我更新这个答案 .
内置的Xcode代码段库仅
objective-c
语言为dispatch_after
. 人们也可以为Swift
创建自己的 Custom Code Snippet .在Xcode中写下这个 .
拖动此代码并将其放在代码段库区域中 .
在代码片段列表的底部,会有一个名为
My Code Snippet
的新实体 . 编辑此 Headers . 当您在Xcode中输入 Completion Shortcut 时输入建议 .有关详细信息,请参阅CreatingaCustomCodeSnippet .
更新Swift 3
拖动此代码并将其放在代码段库区域中 .
PerformSelector:WithObject总是接受一个对象,所以为了传递像int / double / float等参数.....你可以使用这样的东西 .
// NSNumber是一个对象..
同样的方法你可以使用[NSNumber numberWithInt:]等....在接收方法中你可以将数字转换为格式为[number int]或[number double] .
BlocksKit框架中有一个很好的 .
BlocksKit
(和 class )
BBlocksKit.m
Swift 3 & Xcode 8.3.2
这段代码对你有所帮助,我也加了解释
扩展Jaime Cham的答案我创建了一个NSObject Blocks类别,如下所示 . 我觉得这些方法更符合现有的
performSelector:
NSObject方法NSObject+Blocks.h
NSObject+Blocks.m
并使用如下:
您可以稍后使用
dispatch_after
来调用块 . 在Xcode中,开始输入dispatch_after
并点击Enter
以自动完成以下内容:这是一个以两个浮点数作为“参数”的示例 . 您不必依赖任何类型的宏,并且代码的意图非常明确:
Swift 3,Swift 4
斯威夫特2
目标C.
以下是在Swift延迟后触发块的方法:
它包含在my repo中作为标准函数 .
我想你正在寻找
dispatch_after()
. 它要求您的块不接受任何参数,但您可以让块从本地范围捕获这些变量 .更多:https://developer.apple.com/documentation/dispatch/1452876-dispatch_after
也许比通过GCD,在某个类(例如“Util”)或者对象上的类别更简单:
所以使用:
您可以将参数包装在自己的类中,也可以将方法调用包装在不需要在基本类型中传递的方法中 . 然后在延迟后调用该方法,并在该方法中执行您希望执行的选择器 .
在swift 3中,我们可以简单地使用DispatchQueue.main.asyncAfter函数在'n'秒延迟后触发任何函数或动作 . 在代码中,我们在1秒后设置了延迟 . 您可以调用此函数体内的任何函数,该函数将在延迟1秒后触发 .
这是一个 handy helper ,以防止反复拨打恼人的GCD电话:
现在你只需 delay your code on the Main thread 就像这样:
如果你想 delay your code to different thread :
如果您更喜欢 Framework ,它还有一些更方便的功能,那么请查看 HandySwift . 您可以将它添加到项目 via Carthage 然后使用它与上面的示例完全相同:
这是Swift 3在延迟后排队工作的方法 .