objective-c - 在 Swift 中使用 Obj-C 完成 block

标签 objective-c swift completion-block

在 Objective-C 中,我有一个完成 block 类定义为:

文件.h

typedef void (^MYCompletionBlock)(BOOL success, NSDictionary *result, NSError *error);

然后,在 Swift 文件中,我尝试按如下方式使用完成 block :

Swift.swift

class MyClass: NSObject{
     ...

     func MyFunction() -> Void {
          ...
          objcMethod(param1, withCompletion: {(MYCompletionBlock) -> Void in
               if (success){ // Error:"Use of unresolved identifier 'success'"
               }
          }
          ... 
     }
     ...
}

但是,我不断收到错误消息:“使用未解析的标识符‘成功’”。

我也尝试过以下方法:

objcMethod(param1, withCompletion: {(success:Bool, result: NSDictionary, error:NSError) -> Void in
     if (success){ // Error:"Cannot convert value of type '(Bool, NSDictionary, NSError) -> Void' to expected argument type "MYCompletionBlock!" 
     }
}

有人可以帮助我了解如何在 Swift 中正确指定 Obj-C 完成 block 吗?

最佳答案

鉴于您的闭包没有指定可空性限定符(它们几乎肯定是可选的),我们可以安全地假设您的 Objective-C API 没有针对可空性进行审核。因此,Swift 会将指针视为隐式展开的可选值。此外,现在 NSDictionary 被映射到 [NSObject : AnyObject] Swift 字典。

因此,它将是:

obj.objcMethod(param) { (success: Bool, result: [NSObject : AnyObject]!, error: NSError!) in
    if success {
        // do something
    }
}

或者,正如 Kobi 指出的那样,您可以让编译器推断类型:

obj.objcMethod(param) { success, result, error in
    if success {
        // do something
    }
}

请注意,您不必自己记住这一点。您可以在输入代码时利用 Xcode 的代码完成功能。因此,键入足以匹配方法名称的内容,当它匹配 objcMethod 时,然后按回车键:

enter image description here

当您到达 MYCompletionBlock 时,再次按回车键,它将显示正确的签名:

enter image description here


如果这个 Objective-C 方法是我自己的类,我会审核它的可空性。因此,例如,假设 param 是可选的,闭包是必需的,并且 resulterror 是可选的,您可以定义它像这样:

NS_ASSUME_NONNULL_BEGIN

typedef void (^MYCompletionBlock)(BOOL success, NSDictionary * _Nullable result, NSError * _Nullable error);

@interface MyObject : NSObject

- (void)objcMethod:(NSDictionary * _Nullable)param1 withCompletionHandler:(MYCompletionBlock)completionHandler;

@end

NS_ASSUME_NONNULL_END

而且,如果是这种情况,您的 Swift 代码会这样调用它:

obj.objcMethod(param) { (success: Bool, result: [NSObject : AnyObject]?, error: NSError?) in
    if success {
        // do something
    }
}

或者,再次让编译器为您推断类型(但这次它们将被推断为未隐式展开的可选类型):

obj.objcMethod(param) { success, result, error in
    if success {
        // do something
    }
}

关于objective-c - 在 Swift 中使用 Obj-C 完成 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37356631/

相关文章:

ios - SWIFT 从另一个 Controller 访问数据

swift - 完成 block 不返回任何内容

ios - Swift 3.0 无法将 (_, _)->() 类型的值转换为预期参数类型 'ObjectsOrErrorBlock'

ios - 如何表示 nil Error Swift 完成 block

objective-c - NSManagedObject 实现协议(protocol) - 由于 @dynamic 引起的警告

Swift facebook Messenger 用户照片

objective-c - OCLint 在 html 报告文件中出现编译错误,但我的项目构建成功。为什么

swift - 如何编写一个接受字符串并删除第一个元音之前的所有辅音的函数

javascript - 从 UIWebView 中提取文本

ios - UIAlertController 操作不起作用?