可选的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
或者false
的success
值)。 显然,这些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演示,请参阅此答案的前一个修订 。)