Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 确保在*all*代码路径中使用参数的方法?_Swift - Fatal编程技术网

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
可以传递给另一个方法,稍后在异步调用中执行。因此,它实际上是强制在所有代码路径中使用参数,而不必调用。更新我的问题,很抱歉。