【问题标题】:Method cannot be marked @objc because its result type cannot be represented in Objective-C方法不能被标记为@objc,因为它的结果类型不能在 Objective-C 中表示
【发布时间】:2018-09-08 04:49:23
【问题描述】:

我在 Objective-C 和 Objective-C 运行时中公开了 swift API。

当我在函数抛出错误之前添加“@objc”时“方法不能被标记为@objc,因为它的结果类型不能在Objective-C中表示”

我的代码在这里

@objc public static func logIn(_ userId: String) -> User? { }

User 是可选结构。如何解决这个问题。

【问题讨论】:

  • 显示class这个函数的声明代码(class这个函数)
  • 公共最终类管理器:NSObject { }
  • 添加你的代码User
  • 用户是一个结构而不是类。
  • @SriMa 目标/选择器无法使用 swift Struct,如果您使用的是我建议您从任何 NSObject 类调用选择器

标签: ios objective-c swift optional-parameters objective-c-runtime


【解决方案1】:

您的类或协议必须由NSObject 或其层次结构中的任何其他类继承(扩展),包含您的代码(函数)和@objc 符号。

例子:

class TestClass {
    public static func logIn(_ userId: String) -> User? { }
}

要在此函数中使用/声明@objc,类必须扩展NSObject(或其层次结构中的任何其他类)

class TestClass {
    @objc public static func logIn(_ userId: String) -> User? { }
}

更新:

struct 可能不适用于 Objective-C 中的可选值,作为一种解决方法,您应该将 Userstruct 更改为 class

试试下面的代码看看:

public class User : NSObject {
    // Your code
}

public final class Manager : NSObject {

    @objc public static func logIn(_ userId: String) -> User? {
        return nil
    }
}

这是编辑器的快照

【讨论】:

  • 用户是结构而不是类。
  • @SriMa struct 可能不适用于 Objective-C 中的可选值,作为一种解决方法,您应该将 Userstruct 更改为 class
【解决方案2】:

如下更改你的类的定义

class User: NSObject {

}

这样这个类将在Objective-C中可用

【讨论】:

    【解决方案3】:

    Objective-C 只能看到 NSObject 派生的类类型。使用:

    class User : NSObject {
    

    }

    【讨论】:

      【解决方案4】:

      关键信息如下:

      用户是可选结构

      如果User 是一个结构,那么它就不能在Objective-C 中表示,就像一个不继承自NSObject 的Swift 类一样。

      为了使方法logIn(_:) 能够被标记为@objc,那么方法声明中引用的每个类型都必须在Objective-C 中表示。您收到错误消息是因为 User 不是。

      要修复它,您要么必须更改 User 的声明:

      struct User {
          // ...
      }
      

      ...到这个:

      class User: NSObject {
          // ...
      }
      

      ...或重新设计logIn(_:),使其不返回User


      您可以找到有关此here 的更多信息。特别是,this answer 提供了以下潜在解决方案:

      我发现最好的方法是包装在一个 Box 类中

      public class Box<T>: NSObject {
          let unbox: T
          init(_ value: T) {
              self.unbox = value
          }
      }
      

      【讨论】:

      • @SriMa 请仔细查看我的代码示例。您不仅要从 NSObject 添加继承,还要将其从 struct 更改为 class
      • @SriMa 您通过说“用户是结构而不是类”来反复回复人们的答案。您需要将其从struct 更改为class;这是大多数答案的精髓。
      • 在这种情况下,请注意我回答的结尾,我说“或重新设计logIn(_:),这样它就不会返回User。”不可能按照您的要求去做; structs 不能在 Objective-C 中表示。
      • @SriMa 我已经编辑了我的答案,以包含来自不同 StackOverflow 答案的另一个潜在解决方案。
      • @SriMa 是的,这是我对我的问题所做的编辑。您可以使用底部定义的Box 类,并使用它来包装User。不过,我会警告您,如果您想将 User 保留为结构,您的选择非常有限,并且您可能会遇到其他问题。
      猜你喜欢
      • 2019-02-24
      • 2016-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-22
      • 1970-01-01
      相关资源
      最近更新 更多