mutating method functions constructors swift closures objective-c-blocks

method - Almacenar un cierre como una variable en Swift



swift method (7)

El compilador se queja

var completionHandler: (Float)->Void = {}

porque el lado derecho no es un cierre de la firma apropiada, es decir, un cierre que toma un argumento de flotación. Lo siguiente asignaría un cierre de "no hacer nada" al manejador de finalización:

var completionHandler: (Float)->Void = { (arg: Float) -> Void in }

y esto puede acortarse a

var completionHandler: (Float)->Void = { arg in }

debido a la inferencia de tipo automático.

Pero lo que probablemente desee es que el manejador de finalización se inicialice a nil de la misma manera que una variable de instancia Objective-C se inicializa a nil . En Swift esto se puede realizar con una opción :

var completionHandler: ((Float)->Void)?

Ahora la propiedad se inicializa automáticamente a nil ("sin valor"). En Swift usaría un enlace opcional para verificar que el controlador de finalización tenga un valor

if let handler = completionHandler { handler(result) }

o encadenamiento opcional:

completionHandler?(result)

En Objective-C, puede definir la entrada y salida de un bloque, almacenar uno de esos bloques que se pasan a un método, y luego usar ese bloque más adelante:

// in .h typedef void (^APLCalibrationProgressHandler)(float percentComplete); typedef void (^APLCalibrationCompletionHandler)(NSInteger measuredPower, NSError *error); // in .m @property (strong) APLCalibrationProgressHandler progressHandler; @property (strong) APLCalibrationCompletionHandler completionHandler; - (id)initWithRegion:(CLBeaconRegion *)region completionHandler:(APLCalibrationCompletionHandler)handler { self = [super init]; if(self) { ... _completionHandler = [handler copy]; .. } return self; } - (void)performCalibrationWithProgressHandler:(APLCalibrationProgressHandler)handler { ... self.progressHandler = [handler copy]; ... dispatch_async(dispatch_get_main_queue(), ^{ _completionHandler(0, error); }); ... }

Así que estoy tratando de hacer el equivalente en Swift:

var completionHandler:(Float)->Void={} init() { locationManager = CLLocationManager() region = CLBeaconRegion() timer = NSTimer() } convenience init(region: CLBeaconRegion, handler:((Float)->Void)) { self.init() locationManager.delegate = self self.region = region completionHandler = handler rangedBeacons = NSMutableArray() }

Al compilador no le gusta esa declaración de finalización Handler. No es que lo culpe, pero, ¿cómo puedo definir un cierre que pueda establecerse y usarse más adelante en Swift?


Esto también funciona:

var exeBlk = { () -> Void in } exeBlk = { //do something } //instead of nil: exeBlk = {}


He proporcionado un ejemplo que no estoy seguro de si esto es lo que buscas.

var completionHandler: (value: Float) -> (); func printFloat(value: Float) { println(value) } completionHandler = printFloat completionHandler(value: 5)

Simplemente imprime 5 usando la variable completionHandler declarada.


In swift 4. Creé una variable de cierre que contiene dos parámetros de diccionario y bool.

var completionHandler:([String:Any], Bool)->Void = { dict, success in if sucess { print(dict) } }

Llamar a la variable de cierre

self.completionHandler(["name":"Gurjinder singh"],true)


Los cierres se pueden declarar como typealias como a continuación

typealias Completion = (Bool, Any, Error) -> Void

Si desea utilizar en su función en cualquier parte del código; puedes escribir como variable normal

func xyz(with param1: String, completion: Completion) { }


Para mí, lo siguiente fue trabajar:

var completionHandler:((Float)->Void)!


C objetivo

@interface PopupView : UIView @property (nonatomic, copy) void (^onHideComplete)(); @end @interface PopupView () ... - (IBAction)hideButtonDidTouch:(id sender) { // Do something ... // Callback if (onHideComplete) onHideComplete (); } @end PopupView * popupView = [[PopupView alloc] init] popupView.onHideComplete = ^() { ... }

Rápido

class PopupView: UIView { var onHideComplete: (() -> Void)? @IBAction func hideButtonDidTouch(sender: AnyObject) { // Do something .... // Callback if let callback = self.onHideComplete { callback () } } } var popupView = PopupView () popupView.onHideComplete = { () -> Void in ... }