如何将 Swift 结构作为参数传递给 Objective-C 方法

How to pass a Swift struct as a parameter to an Objective-C method

我有一个 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
    }
}

我得到的编译错误信息:

Type 'DemoStruct' does not conform to protocol 'AnyObject'

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

你做不到。

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

You’ll have access to anything within a class or protocol that’s marked with the @objc attribute as long as it’s compatible with Objective-C. This excludes Swift-only features such as those listed here:

  • Generics
  • Tuples
  • Enumerations defined in Swift
  • Structures defined in Swift
  • Top-level functions defined in Swift
  • Global variables defined in Swift
  • Typealiases defined in Swift
  • Swift-style variadics
  • Nested types
  • Curried functions

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

我发现最好的东西是用盒子包裹 class

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

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

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

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

// 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
  }
}