在Swift中将闭包存储为变量 [英] store a closure as a variable in Swift

查看:98
本文介绍了在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)处理程序
{
...

self.progressHandler = ];

...
dispatch_async(dispatch_get_main_queue(),^ {
_completionHandler(0,error);
}
...
}

所以我试图做在Swift中:

  var completionHandler:(Float) - > Void = {} 


init(){
locationManager = CLLocationManager()
region = CLBeaconRegion()
timer = NSTimer()

}

方便init(region:CLBeaconRegion,handler:((Float) - > Void)){
self.init()
locationManager.delegate = self
self.region = region
completionHandler = handler
rangedBeacons = NSMutableArray()
}

像完成声明的Handler。

解决方案

不是我的责任,但我如何定义一个闭包编译器在

上投诉

  var completionHandler:(Float) - > Void = {} 

,因为右侧不是适当签名的关闭,即关闭采用
a float参数。下面将给
完成处理程序分配一个do nothing闭包:

  var completionHandler:(Float) > Void = {
(arg:Float) - >无效于
}

,可缩短为

  var completionHandler:(Float) - > Void = {arg in} 

$

初始化为 nil
,方法与将Objective-C实例变量初始化为 nil 相同。在Swift
中,这可以通过可选实现:

  var completionHandler:( Float) - > Void)? 

现在该属性自动初始化为 nil (没有价值)。
在Swift中,您将使用可选绑定检查
完成处理程序是否具有值

  if let handler = completionHandler {
handler(result)
}

  completionHandler?(result)


In Objective-C, you can define a block's input and output, store one of those blocks that's passed in to a method, then use that block later:

// 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);
            });
     ...
}

So I'm trying to do the equivilant in 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()
}

The compiler doesn't like that declaration of completionHandler. Not that I blame it, but, how do I define a closure that can be set and used later in Swift?

解决方案

The compiler complains on

var completionHandler: (Float)->Void = {}

because the right-hand side is not a closure of the appropriate signature, i.e. a closure taking a float argument. The following would assign a "do nothing" closure to the completion handler:

var completionHandler: (Float)->Void = {
    (arg: Float) -> Void in
}

and this can be shortened to

var completionHandler: (Float)->Void = { arg in }

due to the automatic type inference.

But what you probably want is that the completion handler is initialized to nil in the same way that an Objective-C instance variable is inititialized to nil. In Swift this can be realized with an optional:

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

Now the property is automatically initialized to nil ("no value"). In Swift you would use optional binding to check of a the completion handler has a value

if let handler = completionHandler {
    handler(result)
}

or optional chaining:

completionHandler?(result)

这篇关于在Swift中将闭包存储为变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆