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