optional closure and check if it is nil optional closure and check if it is nil swift swift

optional closure and check if it is nil


You need to wrap your closure signature in parentheses to make the closure itself optional. The way it's written now, the closure returns an optional Void (which doesn't really make sense).

var completionHandler: ((sucsess:Bool!, items:[AnyObject]!)->())?

Some style points and revisions to your example code:

 // Capitalize class names so it's clear what's a class class SomeClass {    // "success" has two "c"s    var completionHandler: ((success:Bool!, items:[AnyObject]!)->())?    var hitpoints = 100    var someset = ["oh no!","avenge me!"]    init() { }    func getHitFunc(impact:Int, passedCompletionsHandler:(success:Bool!, items:[AnyObject]!)->()){        completionHandler = passedCompletionsHandler        hitpoints = hitpoints - impact    }    // You were missing the argument list here:    func checkIfDead() {        if hitpoints <= 0 {            // Rather than checking to see if the completion handler exists, you can            // just call it using optional syntax like this:            completionHandler?(success: true, items: someset)        }        completionHandler = nil    }}


First, in your declaration of the completion handler, you need to declare the whole thing as optional with the use of parentheses:

var completionHandler: ((_ success: Bool, _ items: [Any]?) -> ())?

Or, perhaps better, you can replace that final () with Void:

var completionHandler: ((_ success: Bool, _ items: [Any]?) -> Void)?

Also, note, I don't think you meant to make the Bool optional (because if the closure exists, you presumably always pass a success value of true or false). Clearly, the array of items might well be optional.

Anyway, when done, you'd just make sure to unwrap that optional:

func checkIfDead() {    if hitpoints <= 0 {        completionHandler?(true, items)    }    completionHandler = nil}

This performs the closure if and only if it is not nil, avoiding the need to explicitly check if it was nil.


For what it's worth, this might be a case where your typealias might make this less confusing:

typealias CompletionHandlerClosureType = (_ success: Bool, _ items: [Any]?) -> Void

Then the property is simply:

var completionHandler: CompletionHandlerClosureType?

The function that takes this completionHandler as a optional parameter could do:

func startSomeProcess(passedCompletionHandler: CompletionHandlerClosureType?) {    completionHandler = passedCompletionHandler    // do whatever else you want}

and then the final completion logic is unchanged:

func finishSomeProcess() {    completionHandler?(true, items)    completionHandler = nil}

(Note, the above has been modified for Swift 3. Please see previous revision of this answer if you want to see Swift 2 renditions.)