我看到许多使用类成员变量将后台任务的值传递给完成块的示例:
self.bgTask = UIApplication.sharedApplication()
.beginBackgroundTaskWithName("bg task", expirationHandler: { () -> Void in
UIApplication.sharedApplication().endBackgroundTask(self.bgTask)
self.bgTask = UIBackgroundTaskInvalid
})
Run Code Online (Sandbox Code Playgroud)
如果在第一个后台任务仍在运行时第二次调用此代码,self.bgTask则会被新任务的标识符覆盖,并且UIApplication.sharedApplication().endBackgroundTask(self.bgTask)可能永远不会被调用.
如果我声明一个局部变量,那么它的值在被初始化之前被闭包捕获.也不好.
如何安全地将任务ID传递给完成处理程序?如果我的上述推理错误,请纠正我.
在ObjC中,通常使用__block变量来执行此操作,例如:
__block UIBackgroundTaskIdentifier bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"Expired: %lu", (unsigned long)bgTask);
}];
NSLog(@"Background: %lu", (unsigned long)bgTask);
Run Code Online (Sandbox Code Playgroud)
这捕获bgTask为块的可变变量.复制块时它会移动到堆中,并且局部变量bgTask是指向它的间接指针.请参阅bbum在Blocks Tips&Tricks中更广泛的解释.
如果你想将它分配给一个属性,那很好,但你不需要.
Swift没有__block属性,但它在没有任何帮助的情况下做了正确的事情.你只需要给它一个var工作.
func goBackground() {
let app = UIApplication.sharedApplication()
var bgTask: UIBackgroundTaskIdentifier = 0
bgTask = app.beginBackgroundTaskWithExpirationHandler({
NSLog("Expired: %lu", bgTask)
app.endBackgroundTask(bgTask)
})
NSLog("Background: %lu", bgTask)
}
func applicationDidEnterBackground(application: UIApplication) {
goBackground()
goBackground()
}
Run Code Online (Sandbox Code Playgroud)
同样,没有必要将值存储在属性中,除非您出于某些其他原因需要它.该值作为局部变量存储在闭包内.
这是学习闭包的一个重要的事情,是Swift的一个非常强大的功能.这可以让你这样做:
var n = 0
let nextNat = { n++ }
println(nextNat()) // => 0
println(nextNat()) // => 1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2269 次 |
| 最近记录: |