В Objective-C вы можете определить вход и выход блока, сохранить один из тех блоков, которые передаются в метод, а затем использовать этот блок позже:
// 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);
});
...
}
Итак, я пытаюсь сделать эквивалент в 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()
}
Компилятору не нравится это объявление завершенияHandler. Не то чтобы я винил это, но как мне определить закрытие, которое можно установить и использовать позже в Swift?
swift
closures
objective-c-blocks
Джей Даб
источник
источник
Ответы:
Компилятор жалуется на
var completionHandler: (Float)->Void = {}
потому что правая часть не является закрытием соответствующей сигнатуры, то есть закрытием, принимающим аргумент с плавающей запятой. Следующее будет назначать закрытие "ничего не делать" обработчику завершения:
var completionHandler: (Float)->Void = { (arg: Float) -> Void in }
и это можно сократить до
var completionHandler: (Float)->Void = { arg in }
из-за автоматического вывода типа.
Но вы, вероятно, хотите, чтобы обработчик завершения инициализировался так
nil
же, как инициализируется переменная экземпляра Objective-Cnil
. В Swift это можно реализовать с помощью необязательного :var completionHandler: ((Float)->Void)?
Теперь свойство автоматически инициализируется
nil
(«без значения»). В Swift вы можете использовать необязательную привязку для проверки того, что обработчик завершения имеет значениеif let handler = completionHandler { handler(result) }
или необязательная цепочка:
источник
((Float)->Void)!
то другое, чем((Float)->Void)?
? Не объявляет ли еще неинициализированный необязательный?
параметр по умолчаниюnil
?Цель-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 = ^() { ... }
Swift
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 ... }
источник
Я привел пример, не уверен, что это то, что вам нужно.
var completionHandler: (_ value: Float) -> () func printFloat(value: Float) { print(value) } completionHandler = printFloat completionHandler(5)
Он просто печатает 5, используя
completionHandler
объявленную переменную.источник
В Swift 4 и 5 . Я создал закрывающую переменную, содержащую словарь с двумя параметрами и bool.
var completionHandler:([String:Any], Bool)->Void = { dict, success in if success { print(dict) } }
Вызов закрывающей переменной
self.completionHandler(["name":"Gurjinder singh"],true)
источник
Затворы могут быть объявлены ,
typealias
как показано нижеtypealias Completion = (Bool, Any, Error) -> Void
Если вы хотите использовать в своей функции в любом месте кода; вы можете писать как обычную переменную
func xyz(with param1: String, completion: Completion) { }
источник
Это тоже работает:
var exeBlk = { () -> Void in } exeBlk = { //do something } //instead of nil: exeBlk = {}
источник
Для меня работало следующее:
var completionHandler:((Float)->Void)!
источник