objective-c - 在 Swift 中使用一个返回 Optional 或 Throw 的 Objective-C 函数

标签 objective-c swift option-type throw bridging-header

我正在开发一个需要与现有 Objective-C API 交互的快速项目。不过,我在使用其中一个功能时遇到了一些障碍。在 objective-c 头文件 (OrderItem.h) 中,我有这个函数定义:

+ (NSString *_Nullable)getOptional:(NSString *_Nonnull)foo error:(NSError *_Nullable *_Nullable)error;

特别要注意最后一个参数;因为它是一个错误指针,所以在 swift 中对此方法的调用需要包装在错误处理程序中(do .. catch)。

对应的.m文件如下:

+ (NSString *)getOptional:(NSString *)foo error:(NSError *__autoreleasing *)error
{
    if([foo isEqualToString:@"abc"])
    {
        return @"abc item";
    }
    else
    {
        if([foo isEqualToString:@"xyz"])
        {
            *error = [[NSError alloc] init];
        }
        return nil;
    }
}

然后在我的 swift 文件中添加了这段代码:

func testGetOptional()
{
    do
    {
        var result:NSString? = try OrderItem.getOptional("abc");
        XCTAssertNotNil(result);
        result = try OrderItem.getOptional("123");
        XCTAssertNil(result);

    }
    catch let error as NSError
    {
        XCTFail("OrderItem lookup should not have thrown an error. Error was " + error.localizedDescription);
    }

}

没什么特别复杂的;对 getOptional 的两次调用实际上都不应该导致错误。但是,当我运行该函数时,“123”案例会爆炸并导致测试失败。当我仔细观察时,我的 objective-c 的桥接版本似乎将返回类型定义为 Nonnull (-> OrderItem),即使我在 objective-c 中明确将其定义为 Nullable。更奇怪的是,如果我在没有最终“错误”参数的情况下声明同一个函数,那么桥接版本将具有正确的 Nullable 返回类型(-> OrderItem?)。

有人可以阐明这里发生的事情吗?更重要的是,有什么方法可以解决这个问题吗?

最佳答案

在 Cocoa 中有一个错误模式,即一个可能失败的方法将有一个返回值和一个间接错误参数。如果是返回对象引用的方法,则模式为

  • 设置间接错误参数指向的引用,

  • 返回

看起来像这样

+(NSString *) getOptional:( NSString *) foo error:(NSError *__autoreleasing *)error
{
   …
   // Error case
   *error = [NSError …];
   return nil;
   …
 }

在 Swift 中,错误被转换为 docatch 结构。因此,从 Swift 的角度来看,永远不会使用表示错误的 nil 返回值,因为执行已被捕获。因此它是不可空的。

关于objective-c - 在 Swift 中使用一个返回 Optional 或 Throw 的 Objective-C 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34187188/

相关文章:

ios - JSExport 一个多参数的 Objective-C 方法不能吗?

iphone - 是否可以将弹出框内的导航栏高度更改为默认高度?

ios - WatchKit-区分表中的表(table, didSelectRowAtIndex)

swift - 是否可以在不声明的情况下在 Swift 中抛出 "RuntimeException"?

ios - 为什么转换后的 UIView 会与层次结构中更高层的其他 View 重叠?

ios - 我们可以获得测试卡来在 BrainTree SDK 中测试 ApplePay 吗?

ios - 警告 "Mapping architecture arm64 to x86_64"是什么意思?

c++ - boost::可选抽象类类型

swift - 为什么 Swift 的大于或小于运算符不能比较可选项,而等于运算符可以?

Swift 如何从条件绑定(bind)必须具有可选类型的 do catch 返回元组?