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