examples closure swift closures block

examples - shorthand closure swift



Cierre opcional y compruebe si es nulo. (2)

Debe envolver su firma de cierre entre paréntesis para hacer que el cierre sea opcional. Tal como está escrito ahora, el cierre devuelve un Vacío opcional (que en realidad no tiene sentido).

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

Algunos puntos de estilo y revisiones a su código de ejemplo:

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

Entonces, lo que quiero es que una clase se le pase un cierre en una función, también puede que en algún momento quiera ignorar ese cierre. ¿Cómo puedo verificar si la variable de cierre está configurada y cómo puedo eliminarla cuando haya terminado con ella?

No se puede invocar ''! ='' Con una lista de argumentos de tipo ''(@lvalue (sucsess: Bool !, productos: [AnyObject]!) -> (), NilLiteralConvertible)'' Type ''(sucsess: Bool! Products: [AnyObject ]!) -> ()? '' No cumple con el protocolo ''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'' } } }


Primero, en su declaración del controlador de finalización, debe declarar todo como opcional con el uso de paréntesis:

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

O, quizás mejor, puedes reemplazar ese final () con Void :

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

Además, tenga en cuenta que no creo que haya pensado que el Bool opcional (porque si existe el cierre, presumiblemente siempre pasa un valor de success true o false ). Claramente, la matriz de items podría ser opcional.

De todos modos, cuando termines, te asegurarás de desenvolver ese opcional:

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

Esto realiza el cierre si y solo si no es nil , evitando la necesidad de verificar explícitamente si era nil .

Para lo que vale, este podría ser un caso en el que sus typealias puedan hacer esto menos confuso:

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

Entonces la propiedad es simplemente:

var completionHandler: CompletionHandlerClosureType?

La función que toma a este completionHandler como un parámetro opcional podría hacer:

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

y luego la lógica de finalización final se mantiene sin cambios:

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

(Tenga en cuenta que lo anterior se ha modificado para Swift 3. Consulte la revisión anterior de esta respuesta si desea ver las representaciones de Swift 2).