在swift / objective-c

时间:2016-02-23 21:24:19

标签: objective-c swift objective-c-blocks

我试图将一个Swift函数(带有多个参数,定义为闭包)传递给Objective-C函数。从技术上讲,该函数是在Objective-C ++中定义的,但是我在标题级遇到了一个问题,所以它应该等同于这个问题。

在Objective-C标题中,我将其定义为:

@interface MyObjCClass : NSObject
typedef void (^MyCallback)(NSMutableData*, int);

- (void) functionThatTakesACallback: (MyCallback) callback;

在swift中,我试图以这种方式使用它:

self.objcclass!.functionThatTakesACallback()
{
    (values: NSMutableData, length: Int32) -> Void in
        // Do something with this data.
}

我得到的错误是:

  

无法将'(NSMutableData, Int32) -> Void'类型的值转换为预期的参数类型'MyCallback!'

如果我稍微解开一下,将块直接放入Objective-C函数定义(sans typedef):

- (void) functionThatTakesACallback: (void (^)(NSMutableData*, int)) callback;

它给了我更多的帮助:

  

无法将'(NSMutableData, Int32) -> Void'类型的值转换为预期的参数类型'((NSMutableData!, Int32) -> Void)!'

所以,基本上,有没有办法解开这个闭包以适应预期的类型?或者重新定义Objective-C类型?

3 个答案:

答案 0 :(得分:0)

我认为您需要为您的回调参数和函数的回调参数添加可空性属性。有两种方法可以做到。

将可空性注释添加到需要它的每个地方。

@interface MyObjCClass : NSObject
typedef void (^MyCallback)(nonnull NSMutableData*, int);

- (void) functionThatTakesACallback: (nonnull MyCallback) callback;

将整个文件设置为假定为非空

NS_ASSUME_NONNULL_BEGIN

@interface MyObjCClass : NSObject
typedef void (^MyCallback)(NSMutableData*, int);

- (void) functionThatTakesACallback: (MyCallback) callback;

@end

NS_ASSUME_NONNULL_END

答案 1 :(得分:0)

我实际上只是设法解决了这个问题,但是由于解决方案很简单,但鉴于错误信息却非直观,这里是解决方案:

来自Swift的函数调用实际上必须是:

self.objcclass!.functionThatTakesACallback()
{
    (values: NSMutableData!, length: Int32!) -> Void in
        // Do something with this data.
}

答案 2 :(得分:0)

对于参数values,Objective-C期望指向对象的指针,指针可以是nil。在Swift中,转换为optional值。 optional之后是?,应该打开 - 检查是否为零,如果有对象则返回。

尝试:

self.objcclass!.functionThatTakesACallback() {
  (values: NSMutableData?, length: Int32) -> Void in
    if let values = values { // first values is a local, second values is unwrapped into it
      // Do something with this data.
    }
  }