En Objective-C, vous pouvez définir l'entrée et la sortie d'un bloc, stocker un de ces blocs qui est passé à une méthode, puis utiliser ce bloc plus tard:
// 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'équivilant 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 de completionHandler. 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?
swift
closures
objective-c-blocks
Jay Dub
la source
la source
Réponses:
Le compilateur se plaint de
car le côté droit n'est pas une fermeture de la signature appropriée, c'est à dire une fermeture prenant un argument float. Ce qui suit attribuerait une fermeture "ne rien faire" au gestionnaire d'achèvement:
et cela peut être raccourci à
en raison de l'inférence de type automatique.
Mais ce que vous voulez probablement, c'est que le gestionnaire de complétion soit initialisé de
nil
la même manière qu'une variable d'instance Objective-C est initialiséenil
. Dans Swift, cela peut être réalisé avec une option :Maintenant, la propriété est automatiquement initialisée à
nil
("aucune valeur"). Dans Swift, vous utiliseriez une liaison facultative pour vérifier si le gestionnaire d'achèvement a une valeurou chaînage optionnel:
la source
((Float)->Void)!
différente de((Float)->Void)?
? Ne déclare pas un optionnel non initialisé avec la?
valeur par défautnil
déjà?Objectif c
Rapide
la source
J'ai donné un exemple, je ne sais pas si c'est ce que vous recherchez.
Il imprime simplement 5 en utilisant la
completionHandler
variable déclarée.la source
Dans Swift 4 et 5 . J'ai créé une variable de fermeture contenant deux dictionnaire de paramètres et un booléen.
Appel de la variable de fermeture
la source
Les fermetures peuvent être déclarées
typealias
comme ci-dessousSi vous souhaitez utiliser dans votre fonction n'importe où dans le code; vous pouvez écrire comme une variable normale
la source
Cela fonctionne aussi:
la source
Pour moi, suivre fonctionnait:
la source