【问题标题】:How to pass a Swift struct as a parameter to an Objective-C method如何将 Swift 结构作为参数传递给 Objective-C 方法
【发布时间】:2021-11-26 16:10:36
【问题描述】:

我有一个 Objective-C 方法,它接受 id 类型的参数,我想向它传递一个 Swift 结构。

ObjcClass.m文件:

@implementation ObjcClass
+ (void)addListener:(id)listener {
    // Do something with listener
}

DemoStruct.swift文件:

struct DemoStruct {
    func registerAsListener() {
        ObjcClass.addListener(self) // Can't find a way to do this
    }
}

我得到的编译错误信息:

类型“DemoStruct”不符合协议“AnyObject”

所以我的问题是,如何让 Objective-C 方法接受 Any 而不是 AnyObject 并且有这样的事情吗?

【问题讨论】:

    标签: objective-c swift struct


    【解决方案1】:

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

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

    【讨论】:

    • 哇,这是一个优雅的解决方案。 Xcode 7 beta 3。我必须继承 NSObject。
    【解决方案2】:

    你做不到。

    不能从 Objective-C 访问 Swift 结构。这在 Apple 的“Using Swift With Cocoa and Objective-C”一书中有说明:

    只要与 Objective-C 兼容,您就可以访问带有 @objc 属性的类或协议中的任何内容。这不包括仅 Swift 的功能,例如此处列出的功能:

    • 泛型
    • 元组
    • Swift 中定义的枚举
    • Swift 中定义的结构
    • Swift 中定义的顶级函数
    • Swift 中定义的全局变量
    • Swift 中定义的类型别名
    • Swift 风格的可变参数
    • 嵌套类型
    • 柯里化函数

    摘自:Apple Inc.“将 Swift 与 Cocoa 和 Objective-C 结合使用”。电子书。 https://itun.es/gb/1u3-0.l

    【讨论】:

    • 谢谢@jrturton,有什么好方法可以绕过它?那么可能是一个虚拟包装类?
    • 也许,或者你可以传递给 objc 友好的表示。取决于你在 Objective-C 领域真正需要什么
    • 对 Enums 的功能可用性进行了修正:“在没有 Int 原始值类型的 Swift 中定义的枚举”
    【解决方案3】:

    补充 Edward Ashak 的回答,我们可以使用以下扩展。所以在 Objective-C 部分的某个地方可以声明一个容器属性:

    // An object that holds our Swift struct instance:
    @property (nonatomic, strong) NSObject* pocObject;
    

    在 Swift 部分,我们声明了 struct 本身和一堆助手:

    // The struct we are boxing inside pocObject:
    struct POCWithCheck: Decodable {
     ...
    }
    
    @objc class POCWithCheckBox: NSObject {
      let unbox: POCWithCheck
        init(_ value: POCWithCheck) {
          self.unbox = value
        }
    }
    
    extension POCWithCheck {
      func asNSObject() -> NSObject {
        return POCWithCheckBox(self)
      }
    }
    
    extension NSObject {
      func asPOCWithCheck() -> POCWithCheck? {
        return (self as? POCWithCheckBox)?.unbox
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-09-13
      • 1970-01-01
      • 1970-01-01
      • 2021-04-30
      • 1970-01-01
      • 2023-03-13
      • 2014-07-14
      • 1970-01-01
      • 2021-06-29
      相关资源
      最近更新 更多