Swift嵌套函数与Closure变量

时间:2016-08-23 22:36:19

标签: swift

我想创建一个从CloudKit获取记录的函数,如果它遇到临时网络错误,该函数应该重试。

func fetchRecord(withRecordID recordID: CKRecordID, returnBlock: (optError: ErrorType?) -> Void){

    func internalReturnBlock(optError optError: ErrorType?){
        if NSThread.isMainThread() {
            returnBlock(optError: optError)
        }
        else{
            dispatch_async(dispatch_get_main_queue(), { 
                returnBlock(optError: optError)
            })
        }
    }

    func internalWork(){
        privateDB.fetchRecordWithID(recordID) { (optRecord, optError) in
            if let error = optError{
                // IF NETWORK ERROR RETRY
                internalWork()
            }
            else{
                internalReturnBlock(optError: nil)
            }
        }
    }

    internalWork()
}

这里我定义了这样的函数(简化),如果fetch遇到错误,它会通过调用嵌套函数internalWork()来重试

我的问题是使用嵌套函数或创建局部闭包变量之间的区别是什么? 例如,在这里我将internalReturnBlock更改为闭包变量:

func fetchRecord2(withRecordID recordID: CKRecordID, returnBlock: (optError: ErrorType?) -> Void){

    var internalReturnBlock = { (optError: NSError?) in
        if NSThread.isMainThread() {
            returnBlock(optError: optError)
        }
        else{
            dispatch_async(dispatch_get_main_queue(), {
                returnBlock(optError: optError)
            })
        }
    }

    func internalWork(){
        privateDB.fetchRecordWithID(recordID) { (optRecord, optError) in
            if let error = optError{
                // IF NETWORK ERROR RETRY
                internalWork()
            }
            else{
                internalReturnBlock(nil)
            }
        }
    }


    internalWork()
}

使用嵌套函数与变量块之间有什么区别? 有什么优点或问题吗?

1 个答案:

答案 0 :(得分:4)

效果没有区别。一个是带有名称的声明函数,另一个是匿名函数。但它们都是功能。函数是Swift中的一个闭包,所以它们都是闭包。

允许匿名函数使用某些形式的缩写,例如在返回值的单行中省略return。但这些缩写都没有产生任何最终的有效差异。

但是,Swift中的匿名函数有一个声明函数没有的特性 - 捕获列表。这有助于避免保留周期。

f {
    [unowned self] in
    return self.name
} 

此外,在声明将其作为参数的函数声明之后定义匿名函数,因此它可以使用该声明中出现的术语:

f(param:String) {
    return param
}

但是如果你没有使用这些功能,那么你使用哪种功能并不重要。他们的工作方式相同。