NSURLSession回调中的“延迟”块未执行

时间:2016-01-17 20:09:04

标签: ios swift nsurlsession

尝试在NSURLSession.A前置条件的回调中使用defer语句通过guard进行检查并返回。

从Swift 2中描述defer的文献中,无论范围如何退出,defer块都应该运行。 (通过return或break语句。)

但是,当在闭包内返回时,defer块不会运行。

此示例代码退出当前作用域,并带有'return'语句作为防护检查的一部分。在游乐场中运行此代码表示不调用延迟块。删除'return'语句会导致延迟块运行。

这是一个错误,还是我对Swift中'延迟'的理解?

let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: sessionConfig)
let request = NSMutableURLRequest(URL: NSURL(string: "http://google.com")!)


let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
    print("Im done!")
    if let err = error {
        print(err.localizedDescription)
        return
    }

    let goingToFail:String? = .None
    guard let something = goingToFail else { return }
    print ("I'm in here now")

    defer {
        // NOT CALLED
        print("deferring!")
    }
}

task.resume()

1 个答案:

答案 0 :(得分:1)

您必须在希望它影响的defer之前定义return

defer {
    // now it will be called
    print("deferring!")
}

print("Im done!")
if let err = error {
    print(err.localizedDescription)
    return
}

let goingToFail:String? = .None
guard let something = goingToFail else { return }
print ("I'm in here now")

或者你可以在第一个之后放置延迟,如果有一个返回,导致守卫执行延迟内容以及块的常规结束。

print("Im done!")
if let err = error {
    print(err.localizedDescription)
    return
}

defer {
    // will only be called if the guard returns or the closure finishes "regular"
    // will not be called by the previous return
    print("deferring!")
}

let goingToFail:String? = .None
guard let something = goingToFail else { return }
print ("I'm in here now")

简化说明:您的代码只是在语句后执行语句。当程序遇到第一个return时,它还不知道可能跟随defer的任何内容。它只是返回。

defer仅影响自身后的所有范围退出。