可选的closures并检查是否为零

所以我想要的是一个可以在函数中传递给它的闭包的类,它也可能在某个时候想要忽略闭包。 我该如何检查是否设置了闭包variables,并且在完成后可以删除它?

(@lvalue(sucsess:Bool!,products:[AnyObject]!) – >()?, NilLiteralConvertible)'Type'(sucsess:Bool !, products:[AnyObject ]!) – >()?' 不符合协议'NilLiteralConvertible'

class someClass{ //typealias completionHandlerClosureType = (sucsess:Bool!, items:[AnyObject]!)->() var completionHandler:(sucsess:Bool!, items:[AnyObject]!)->()? var hitpoints = 100 var someset = ["oh no!","avenge me!"] init(){} func getHitFunc(impact:Int, passedCompletionsHandler:(sucsess:Bool!, items:[AnyObject]!)->()){ completionHandler = passedCompletionsHandler hitpoints = hitpoints - impact } func checkIfDead{ if hitpoints<=0 { // The error received if completionHandler != nil{// Cannot invoke '!=' with an argument list of type //'(@lvalue (sucsess: Bool!, products: [AnyObject]!) -> ()?, NilLiteralConvertible)' //run the handler if dead completionHandler(sucsess: true, items: someset) //do not run it again completionHandler = nil //Type '(sucsess: Bool!, products: [AnyObject]!) -> ()?' does not conform to protocol 'NilLiteralConvertible' } } else{ completionHandler = nil //Type '(sucsess: Bool!, products: [AnyObject]!) -> ()?' does not conform to protocol 'NilLiteralConvertible' } } } 

您需要将您的封闭签名封装在括号内,以使封闭本身可选。 现在写的方式,闭包返回一个可选的Void(这真的没有意义)。

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

您的示例代码的一些样式点和修订:

  // 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 } } 

首先,在完成处理程序的声明中,需要使用括号声明整个事件为可选项:

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

另外,请注意,我不认为你的意图是让Bool可选的(因为如果闭包存在,你可能总是传递一个true或者falsesuccess值)。 显然,这些items可能是可选的。

无论如何,完成后,你只要确保解开这个可选项:

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

当且仅当它不nil ,才执行closures,从而避免需要明确检查是否nil


对于什么是值得的,这可能是一个你的typealias可能会减less混淆的情况:

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

那么财产就是:

 var completionHandler: CompletionHandlerClosureType? 

将这个completionHandler作为一个可选参数的函数可以这样做:

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

然后最终的完成逻辑不变:

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

(请注意,上面已经修改了Swift 3.如果你想看Swift 2演示,请参阅此答案的前一个修订 。)