You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何创建含函数名的独立HID数据映射文件并调用控制器方法?

解决HID按键映射与ViewController方法调用的方案

以下是几种适配你需求的实现方式,均可在独立文件中维护映射表,同时正确调用ViewController内的方法:

方案1:闭包映射(类型安全,推荐)

通过闭包将ViewController的方法与HID原始数据绑定,编译期即可校验正确性,无需额外修饰。

  1. 创建HIDMapping.swift:
import Foundation

// 根据你的实际HID原始数据类型调整,示例用UInt8
typealias HIDRawData = UInt8

struct HIDMapping {
    // 静态存储映射表,支持全局访问
    static var commandMap: [HIDRawData: () -> Void] = [:]
}
  1. 在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修饰。

  1. 创建HIDMapping.swift:
import Foundation

typealias HIDRawData = UInt8

struct HIDMapping {
    // 直接在映射文件中定义数据与Selector的对应
    static let commandMap: [HIDRawData: Selector] = [
        0x01: #selector(ViewController.handleButton1Press),
        0x02: #selector(ViewController.handleButton2Press),
        // 添加其他映射
    ]
}
  1. 在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负责具体执行,适合复杂场景的解耦。

  1. 创建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)
    }
}
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 16:45:45