如何将字典强类型化为EventListenerOptions协议并调用方法?
解决方案
1. 实现协议的具体类
因为@objc协议无法直接实例化,且结构体不能暴露给Objective-C,所以需要创建一个遵循EventListenerOptions协议的类,同时兼顾Swift的类型安全和OC的易用性:
@objc public class EventListenerOptionsImpl: NSObject, EventListenerOptions { @objc public var capture: Bool = false // 便利初始化,支持直接传入capture参数 @objc public convenience init(capture: Bool) { self.init() self.capture = capture } // 可选:支持从字典初始化,兼容你原本想用字典的需求 @objc public convenience init?(dictionary: [String: Any]) { self.init() guard let captureValue = dictionary["capture"] as? Bool else { return nil } self.capture = captureValue } }
2. Swift中调用方法
现在可以直接创建EventListenerOptionsImpl的实例传入,保证类型安全:
// 方式1:直接用指定初始化器 view.addEventListener( "tap" as NSString, { event in print("Got a tap event.") }, EventListenerOptionsImpl(capture: true) ) // 方式2:用字典初始化(如果需要兼容字典场景) if let options = EventListenerOptionsImpl(dictionary: ["capture": true]) { view.addEventListener( "tap" as NSString, { event in print("Got a tap event.") }, options ) }
3. Objective-C中调用方法
这个类在OC中可以直接使用,构造起来非常方便:
EventListenerOptionsImpl *options = [[EventListenerOptionsImpl alloc] initWithCapture:YES]; [view addEventListener:@"tap" callback:^(UIEvent *event) { NSLog(@"Got a tap event."); } options:options]; // 或者用字典初始化 EventListenerOptionsImpl *optionsFromDict = [[EventListenerOptionsImpl alloc] initWithDictionary:@{@"capture": @YES}]; [view addEventListener:@"tap" callback:^(UIEvent *event) { NSLog(@"Got a tap event."); } options:optionsFromDict];
补充说明
- 为什么不能直接用字典转协议:NSDictionary本身并没有遵循
EventListenerOptions协议,强制转换会导致运行时崩溃,编译器警告也明确说明了类型不匹配。 - 这个方案既满足了Swift的类型安全要求,又让Objective-C端可以轻松构造符合要求的对象,完全适配你的需求。
内容的提问来源于stack exchange,提问作者Jamie Birch
相关产品推荐
相关产品推荐

