Stocker une fermeture en tant que variable dans Swift

Dans Objective-C, vous pouvez définir les entrées et les sorties d’un bloc, stocker l’un de ces blocs transmis à une méthode, puis utiliser ce bloc ultérieurement:

// 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); }); ... } 

Donc j’essaye de faire l’équivalent dans 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() } 

Le compilateur n’aime pas cette déclaration d’achèvementHandler. Non pas que je le blâme, mais comment définir une fermeture qui peut être définie et utilisée plus tard dans Swift?

Le compilateur se plaint

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

parce que le côté droit n’est pas une fermeture de la signature appropriée, c.-à-d. une fermeture prenant un argument float. Ce qui suit atsortingbuerait une fermeture “ne rien faire” au gestionnaire d’achèvement:

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

et cela peut être raccourci à

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

en raison de l’inférence de type automatique.

Mais ce que vous voulez probablement, c’est que le gestionnaire d’achèvement soit initialisé à nil de la même manière qu’une variable d’instance Objective-C est initialisée à nil . Dans Swift, cela peut être réalisé avec une option :

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

Maintenant, la propriété est automatiquement initialisée à nil (“no value”). Dans Swift, vous utiliseriez la liaison facultative pour vérifier que le gestionnaire d’achèvement a une valeur

 if let handler = completionHandler { handler(result) } 

ou chaînage facultatif:

 completionHandler?(result) 

Objectif c

 @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 = ^() { ... } 

Rapide

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

J’ai fourni un exemple qui ne permet pas de savoir si c’est ce que vous recherchez.

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

Il imprime simplement 5 en utilisant la variable completionHandler déclarée.

Dans swift 4. J’ai créé une variable de fermeture contenant deux dictionnaire de parameters et bool.

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

Appel de la variable de fermeture

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

Les fermetures peuvent être déclarées comme typealias comme ci-dessous

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

Si vous voulez utiliser dans votre fonction n’importe où dans le code; vous pouvez écrire comme une variable normale

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

Cela fonctionne aussi:

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

Pour moi, la suite travaillait:

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