将闭包作为变量存储在Swift中

将闭包作为变量存储在Swift中,swift,closures,objective-c-blocks,Swift,Closures,Objective C Blocks,在Objective-C中,您可以定义块的输入和输出,存储传入方法的其中一个块,然后稍后使用该块: // in .h typedef void (^APLCalibrationProgressHandler)(float percentComplete); typedef void (^APLCalibrationCompletionHandler)(NSInteger measuredPower, NSError *error); // in .m @pr

在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()
}

编译器不喜欢completionHandler的声明。我并不是责怪它,但是,我如何定义一个可以在以后的Swift中设置和使用的闭包呢?

我提供了一个示例,不确定这是否是您想要的

var completionHandler: (_ value: Float) -> ()

func printFloat(value: Float) {
    print(value)
}

completionHandler = printFloat

completionHandler(5)

它只是使用声明的
completionHandler
变量打印5。

编译器抱怨

var completionHandler: (Float)->Void = {}
因为右侧不是相应签名的闭包,即闭包 浮动参数。下面将为 完成处理程序:

var completionHandler: (Float)->Void = {
    (arg: Float) -> Void in
}
这可以缩短为

var completionHandler: (Float)->Void = { arg in }
由于自动类型推断

但是您可能想要的是完成处理程序被初始化为
nil
与Objective-C实例变量初始化为
nil
的方式相同。迅速地 这可以通过一个可选的:

现在属性自动初始化为
nil
(“无值”)。 在Swift中,您将使用可选绑定来检查 完成处理程序有一个值

if let handler = completionHandler {
    handler(result)
}
或可选链接:

completionHandler?(result)

对我来说,以下几点很有效:

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

目标-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 exeBlk = {
    () -> Void in
}
exeBlk = {
    //do something
}
//instead of nil:
exeBlk = {}

闭包可以声明为
typealias
,如下所示

typealias Completion = (Bool, Any, Error) -> Void
如果你想在你的函数中的任何地方使用代码;你可以像普通变量一样写

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

Swift 4和5中。我创建了一个包含两个参数dictionary和bool的闭包变量

 var completionHandler:([String:Any], Bool)->Void = { dict, success  in
    if success {
      print(dict)
    }
  }
调用闭包变量

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

根据您的需要,在已接受的答案中添加了一个选项。您也可以这样实现它:

var parseCompletion: (() ->Void)!
然后在一些函数中指定给它

func someHavyFunc(completion: @escaping () -> Void){
    self.parseCompletion = completion
}
在第二个函数中使用它

func someSecondFunc(){
    if let completion = self.parseCompletion {
        completion()
    }
}

请注意,
@escaping
参数在这里是必需的

编译时会出现什么错误?“在Swift中,这可以通过使用
((Float)->Void)的隐式展开可选选项或“显式展开”(即常规)选项来实现!”
((浮动)->无效)有任何不同吗?
?使用
默认值将未初始化的可选项声明为
nil
是否已经存在?但是内存管理是否自动正确处理?因为在Obj-C中,您指定属性为“复制”,但swift似乎没有该选项,而是定义为“强”,或者是吗?为什么需要复制它?
func someSecondFunc(){
    if let completion = self.parseCompletion {
        completion()
    }
}