W Objective-C możesz zdefiniować wejście i wyjście bloku, zapisać jeden z tych bloków, który jest przekazany do metody, a następnie użyć tego bloku później:
// 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);
});
...
}
Więc próbuję zrobić to samo w 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()
}
Kompilatorowi nie podoba się ta deklaracja CompleteHandler. Nie to, żebym go winił, ale jak zdefiniować zamknięcie, które można ustawić i użyć później w Swift?
swift
closures
objective-c-blocks
Jay Dub
źródło
źródło
Odpowiedzi:
Kompilator narzeka na
ponieważ prawa strona nie jest zamknięciem odpowiedniego podpisu, czyli domknięciem przyjmującym argument typu float. Poniższe polecenie przypisałoby zamknięcie „nic nie rób” do procedury obsługi zakończenia:
i można to skrócić do
ze względu na automatyczne wnioskowanie o typie.
Ale prawdopodobnie chcesz, aby procedura obsługi zakończenia została zainicjowana
nil
w ten sam sposób, w jaki jest zainicjowana zmienna instancji Objective-Cnil
. W Swift można to zrealizować za pomocą opcjonalnego :Teraz właściwość jest automatycznie inicjalizowana na
nil
(„brak wartości”). W Swift możesz użyć opcjonalnego powiązania, aby sprawdzić, czy program obsługi zakończenia ma wartośćlub opcjonalnie łańcuch:
źródło
((Float)->Void)!
jest inne niż((Float)->Void)?
? Czy nie jest już deklarowanie niezainicjowanego opcjonalnego z?
wartością domyślnąnil
?Cel C
Szybki
źródło
Podałem przykład, nie jestem pewien, czy o to ci chodzi.
Po prostu wypisuje 5 używając
completionHandler
zadeklarowanej zmiennej.źródło
W Swift 4 i 5 . Utworzyłem zmienną zamykającą zawierającą słownik dwóch parametrów i bool.
Wywołanie zmiennej zamknięcia
źródło
Zamknięcia można zadeklarować
typealias
jak poniżejJeśli chcesz użyć swojej funkcji w dowolnym miejscu kodu; możesz pisać jak normalne zmienne
źródło
To też działa:
źródło
U mnie działało:
źródło