无法从Objective-C调用可丢弃的Swift函数

无法从Objective-C调用可丢弃的Swift函数,objective-c,swift,compiler-errors,throwable,Objective C,Swift,Compiler Errors,Throwable,课堂是用Swift写的 @objc class Test: NSObject { @objc func testBoolean() -> Bool { return true } @objc func testOptionalBoolean() -> Bool? { return true } @objc func testThrowableBoolean() throws -> Bool {

课堂是用Swift写的

@objc class Test: NSObject {

    @objc func testBoolean() -> Bool {
        return true
    }

    @objc func testOptionalBoolean() -> Bool? {
        return true
    }

    @objc func testThrowableBoolean() throws -> Bool {
        return true
    }

    @objc func testThrowableOptionalBoolean() throws -> Bool? {
        return true
    }
}
在这些函数中,只有第一个函数是可编译的

其他函数编译器错误, testOptionalBoolean:无法将方法标记为@objc,因为其结果类型无法在Objective-C中表示

testThrowableBoolean:无法将抛出方法标记为@objc,因为它返回类型为“Bool”的值;返回“Void”或连接到Objective-C类的类型

testThrowableOptionalBoolean:无法将方法标记为@objc,因为其结果类型无法在Objective-C中表示


让objc调用者可以使用所有函数的正确方法是什么?

错误消息非常清楚:

  • 可选标量类型不能用作ObjC中的返回类型,因为只有对象可
    为空
  • 为了能够将
    throw
    ing Swift函数转换为ObjC inout
    NSError
    语法,就Swift而言,返回类型必须是
    AnyObject
    (一个类)
  • 例如,您可以将
    Bool
    类型替换为
    NSNumber

    @objc func testOptionalBoolean() -> NSNumber? {
        return true // Yes, returning a Swift Bool is valid
    }
    

    但是,即使使用
    NSNumber
    函数
    testThrowableOptionalBoolean
    也不会编译,因为抛出函数的设计是在成功时返回非可选的

    错误消息非常清楚:

  • 可选标量类型不能用作ObjC中的返回类型,因为只有对象可
    为空
  • 为了能够将
    throw
    ing Swift函数转换为ObjC inout
    NSError
    语法,就Swift而言,返回类型必须是
    AnyObject
    (一个类)
  • 例如,您可以将
    Bool
    类型替换为
    NSNumber

    @objc func testOptionalBoolean() -> NSNumber? {
        return true // Yes, returning a Swift Bool is valid
    }
    
    但即使使用
    NSNumber
    函数
    testThrowableOptionalBoolean
    也不会编译,因为抛出函数的设计是在成功时返回非可选值

    修改
    try?
    的工作方式,以便将嵌套的选项展平为常规选项。这使得它的工作方式与可选链接和条件类型转换相同,这两种方式在早期的Swift版本中都会展平选项


    您可以创建一个对象作为包装器

    @objc类测试:NSObject{
    @objc func testBoolean()->Bool{
    返回真值
    }
    @objc func testOptionalBoolean()->BooleanWrapper{
    返回布尔包装器(true)
    }
    @objc func testThrowableBoolean()抛出->布尔包装器{
    返回布尔包装器(true)
    }
    }
    
    用法

    如果let wrapper=try?test.testThrowableBoolean(){
    打印(wrapper.bool)
    }
    
    包装器

    @objc class BooleanWrapper: NSObject {
    
        let bool: Bool
    
        init(_ bool: Bool) {
            self.bool = bool
        }
    }
    
    修改
    try?
    的工作方式,以便将嵌套的选项展平为常规选项。这使得它的工作方式与可选链接和条件类型转换相同,这两种方式在早期的Swift版本中都会展平选项


    您可以创建一个对象作为包装器

    @objc类测试:NSObject{
    @objc func testBoolean()->Bool{
    返回真值
    }
    @objc func testOptionalBoolean()->BooleanWrapper{
    返回布尔包装器(true)
    }
    @objc func testThrowableBoolean()抛出->布尔包装器{
    返回布尔包装器(true)
    }
    }
    
    用法

    如果let wrapper=try?test.testThrowableBoolean(){
    打印(wrapper.bool)
    }
    
    包装器

    @objc class BooleanWrapper: NSObject {
    
        let bool: Bool
    
        init(_ bool: Bool) {
            self.bool = bool
        }
    }
    

    你还是想在Swift中以同样的方式调用这些方法,对吗?@Sweeper当然可以。你介意创建这些方法的副本吗(不是它们的主体的副本,只是标题)?例如,您可以编写另一个方法
    @objc func testOptionalBoolean()->NSNumber?{return testOptionalBoolean().map(NSNumber.init(value:))}
    但是我知道有些人不喜欢有两个具有相同名称和参数的方法。return
    NSNumber
    编译器投诉的地方您仍然希望以相同的方式在Swift中调用它们,对吗?@Sweeper当然可以。你介意创建这些方法的副本吗(不是它们主体的副本,只是标题)?例如,您可以编写另一个方法
    @objc func testOptionalBoolean()->NSNumber?{return testOptionalBoolean().map(NSNumber.init(value:))}
    但我知道有些人不喜欢有两个名称和参数相同的方法。return
    NSNumber
    编译器在哪里投诉如果我想返回字符串或数组呢?没有通用的解决方案或解决方法吗?如果我想返回字符串或数组怎么办?没有通用的解决方案或解决方法吗?