Swift 确保在*all*代码路径中使用参数的方法?
假设我有一个具有此功能的Swift 确保在*all*代码路径中使用参数的方法?,swift,Swift,假设我有一个具有此功能的通知管理器: func receivedRemoteNotification(userInfo: [NSObject: AnyObject], fetchCompletionHandler: UIBackgroundFetchResult -> Void) { guard isValidPayload(userInfo) else { fetchCompletionHandler(.Failed) return }
通知管理器
:
func receivedRemoteNotification(userInfo: [NSObject: AnyObject], fetchCompletionHandler: UIBackgroundFetchResult -> Void) {
guard isValidPayload(userInfo) else {
fetchCompletionHandler(.Failed)
return
}
doSomethingAsyncWithCompletionHandler(fetchCompletionHandler)
}
有没有办法告诉编译器无论代码路径是什么,都必须调用
fetchCompletionHandler
您可以使用延迟
块指定当前函数结束前要执行的一些代码
func foo() {
defer {
print("This will always be printed before the end")
}
print("Some code")
}
foo()
> Some code
> This will always be printed before the end
func receivedRemoteNotification(userInfo: [NSObject: AnyObject], fetchCompletionHandler: UIBackgroundFetchResult -> ()) {
let result: UIBackgroundFetchResult
defer {
fetchCompletionHandler(result)
}
guard isValidPayload(userInfo) else {
result = .Failed // if you remove this you get a compiler error
return
}
result = .NewData // if you remove this you get a compiler error
}
所以你可以这样更新你的函数
func receivedRemoteNotification(userInfo: [NSObject: AnyObject], fetchCompletionHandler: UIBackgroundFetchResult -> Void) {
defer {
// call fetchCompletionHandler here
}
guard isValidPayload(userInfo) else {
fetchCompletionHandler(.Failed)
return
}
fetchCompletionHandler(.NewData)
}
当然要注意避免多次通话
更新
Swift有一种机制,可以发现代码的每个可能分支在使用之前都会初始化一个常量
您可以利用这种技术声明一个必须初始化的常量
let result: UIBackgroundFetchResult
并添加一个defer
块,其中使用前面的常量调用fetchCompletionHandler
defer {
fetchCompletionHandler(result)
}
现在,编译器将强制您在当前函数结束之前在每个可能的分支中填充result
func foo() {
defer {
print("This will always be printed before the end")
}
print("Some code")
}
foo()
> Some code
> This will always be printed before the end
func receivedRemoteNotification(userInfo: [NSObject: AnyObject], fetchCompletionHandler: UIBackgroundFetchResult -> ()) {
let result: UIBackgroundFetchResult
defer {
fetchCompletionHandler(result)
}
guard isValidPayload(userInfo) else {
result = .Failed // if you remove this you get a compiler error
return
}
result = .NewData // if you remove this you get a compiler error
}
我喜欢这个想法,尽管如何调用完成处理程序取决于函数的代码路径,这就是为什么我希望这是来自编译器的警告。绝对是一个很好的选择。是的,这是一个非常好的技巧,完美地回答了目前所说的问题。我忘记添加的是,
fetchCompletionHandler
可以传递给另一个方法,稍后在异步调用中执行。因此,它实际上是强制在所有代码路径中使用参数,而不必调用。更新我的问题,很抱歉。