Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift nested functions vs Closure Variables

Tags:

swift

I want to make a function that fetches a record from CloudKit, if it encounters a temporary network error the function should retry.

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()
}

Here I define such function (simplified), If the fetch encounters an error it retries by calling the nested function internalWork()

My question is what would be the difference between using nested functions or creating local closure variables? For example, here I change the internalReturnBlock to a closure variable:

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()
}

What are the differences between using a nested function vs a variable block? Any advantages or problems?

like image 840
the Reverend Avatar asked Aug 23 '16 22:08

the Reverend


1 Answers

There is no difference in effect. One is a declared function with a name, the other is anonymous. But they are both functions. And a function is a closure in Swift, so they are both closures.

An anonymous function is permitted to use some abbreviations of form, such as the omission of return in a one-liner that returns a value. But none of those abbreviations makes any ultimate effective difference.

However, an anonymous function in Swift has one feature a declared function does not — a capture list. This can help avoid retain cycles.

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

Also, an anonymous function is defined after the declaration of the function that takes it as a parameter, so it can use terms that appear in that declaration:

f(param:String) {
    return param
}

But if you are not using those features, then it doesn't matter which you use. They work identically.

like image 144
matt Avatar answered Sep 28 '22 06:09

matt