gpt4 book ai didi

swift - 确保在*所有* 代码路径中使用参数的方法?

转载 作者:行者123 更新时间:2023-11-28 12:59:45 25 4
gpt4 key购买 nike

假设我有一个具有此功能的 NotificationManager:

func receivedRemoteNotification(userInfo: [NSObject: AnyObject], fetchCompletionHandler: UIBackgroundFetchResult -> Void) {
guard isValidPayload(userInfo) else {
fetchCompletionHandler(.Failed)
return
}

doSomethingAsyncWithCompletionHandler(fetchCompletionHandler)
}

有没有办法告诉编译器必须始终调用fetchCompletionHandler,无论代码路径是什么?

最佳答案

您可以使用 defer block 来指定在当前函数结束之前要执行的一些代码。

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 -> Void) {
defer {
// call fetchCompletionHandler here
}

guard isValidPayload(userInfo) else {
fetchCompletionHandler(.Failed)
return
}

fetchCompletionHandler(.NewData)
}

当然要注意避免多次调用。

更新

Swift 有一种机制可以发现代码的每个可能分支在使用前都初始化了一个常量。

您可以利用这种声明必须初始化的常量的技术

let result: UIBackgroundFetchResult

并添加一个 defer block ,其中 fetchCompletionHandler 是用先前的常量调用的。

defer {
fetchCompletionHandler(result)
}

现在编译器将强制您在当前函数结束之前在每个可能的分支中填充result

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
}

关于swift - 确保在*所有* 代码路径中使用参数的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34165231/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com