optional closure and check if it is nil
Solution 1:
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
}
}
Solution 2:
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.)