Swift中如何创建含函数名的独立HID数据映射文件并调用控制器方法?
解决HID按键映射与ViewController方法调用的方案
以下是几种适配你需求的实现方式,均可在独立文件中维护映射表,同时正确调用ViewController内的方法:
方案1:闭包映射(类型安全,推荐)
通过闭包将ViewController的方法与HID原始数据绑定,编译期即可校验正确性,无需额外修饰。
- 创建HIDMapping.swift:
import Foundation // 根据你的实际HID原始数据类型调整,示例用UInt8 typealias HIDRawData = UInt8 struct HIDMapping { // 静态存储映射表,支持全局访问 static var commandMap: [HIDRawData: () -> Void] = [:] }
- 在ViewController中初始化映射并调用:
class ViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() // 绑定HID数据与ViewController的方法 HIDMapping.commandMap = [ 0x01: self.handleButton1Press, 0x02: self.handleButton2Press, // 添加其他按键映射 ] } // 接收HID原始数据的方法 func receivedHIDRawData(_ data: HIDRawData) { // 从映射表取出闭包并执行 HIDMapping.commandMap[data]?() } // 实际处理按键的方法 private func handleButton1Press() { // 按钮1的业务逻辑 } private func handleButton2Press() { // 按钮2的业务逻辑 } }
方案2:Selector映射(适合动态场景)
借助Objective-C的Selector机制实现,可直接在映射文件中定义数据与方法的对应,但需给目标方法添加@objc修饰。
- 创建HIDMapping.swift:
import Foundation typealias HIDRawData = UInt8 struct HIDMapping { // 直接在映射文件中定义数据与Selector的对应 static let commandMap: [HIDRawData: Selector] = [ 0x01: #selector(ViewController.handleButton1Press), 0x02: #selector(ViewController.handleButton2Press), // 添加其他映射 ] }
- 在ViewController中实现方法并调用:
class ViewController: NSViewController { func receivedHIDRawData(_ data: HIDRawData) { guard let selector = HIDMapping.commandMap[data], self.responds(to: selector) else { return } // 执行对应的方法 self.perform(selector) } // 必须添加@objc修饰,才能被Selector识别 @objc func handleButton1Press() { // 按钮1逻辑 } @objc func handleButton2Press() { // 按钮2逻辑 } }
方案3:协议代理模式(解耦逻辑与实现)
通过协议分离HID操作的接口与实现,映射文件负责分发指令,ViewController负责具体执行,适合复杂场景的解耦。
- 创建HIDMapping.swift:
import Foundation typealias HIDRawData = UInt8 // 定义HID指令处理的协议 protocol HIDCommandHandler: AnyObject { func handleButton1Press() func handleButton2Press() // 添加其他需要的操作方法 } struct HIDMapping { // 弱引用代理对象,避免循环引用 weak var handler: HIDCommandHandler? // 映射表:原始数据 -> 代理方法调用逻辑 private let commandMap: [HIDRawData: (HIDCommandHandler) -> Void] = [ 0x01: { $0.handleButton1Press() }, 0x02: { $0.handleButton2Press() }, // 添加其他映射 ] // 执行对应指令 func executeCommand(for data: HIDRawData) { guard let action = commandMap[data], let handler = handler else { return } action(handler) } }
- 在ViewController中实现协议并调用:
class ViewController: NSViewController, HIDCommandHandler { // 创建映射实例 private let hidMapping = HIDMapping() override func viewDidLoad() { super.viewDidLoad() // 设置代理为当前ViewController hidMapping.handler = self } func receivedHIDRawData(_ data: HIDRawData) { // 委托映射文件执行对应指令 hidMapping.executeCommand(for: data) } // 实现协议中的方法 func handleButton1Press() { // 按钮1逻辑 } func handleButton2Press() { // 按钮2逻辑 } }
内容的提问来源于stack exchange,提问作者Ryan H
相关产品推荐
相关产品推荐

