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