Xcode游戏项目中NotificationCenter.addObserver调用及手柄检测问题
iOS游戏手柄连接通知监听失效排查与解决建议
1. 检查通知注册的时机与对象生命周期
- 若项目采用iOS 13+的
SceneDelegate架构,AppDelegate的初始化逻辑仅在App启动时执行一次,后续场景重建时观察者可能已失效。建议将通知注册移至GameViewController的viewDidLoad或viewWillAppear方法中,贴合游戏运行的生命周期。 - 注册通知时明确指定
object: nil,确保监听所有发送者的手柄通知,示例代码:NotificationCenter.default.addObserver(self, selector: #selector(connectControllers(_:)), name: .GCControllerDidConnect, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(disconnectControllers(_:)), name: .GCControllerDidDisconnect, object: nil)
2. 验证选择器方法的正确性
- 选择器方法必须标记
@objc且接收Notification参数,否则无法被通知中心调用,示例:@objc func connectControllers(_ notification: Notification) { guard let controller = notification.object as? GCController else { return } print("手柄已连接: \(controller.vendorName ?? "未知设备")") } @objc func disconnectControllers(_ notification: Notification) { guard let controller = notification.object as? GCController else { return } print("手柄已断开: \(controller.vendorName ?? "未知设备")") } - 避免将方法设为
private,若必须私有需添加@objc private修饰。
3. 确认GameController框架配置
- 在使用手柄逻辑的文件顶部导入框架:
import GameController - iOS 13+需在
Info.plist中添加蓝牙权限描述,比如NSBluetoothAlwaysUsageDescription,说明App需要蓝牙权限的原因,否则系统会阻止手柄连接。 - 注册通知后主动触发手柄扫描:
GCController.startWirelessControllerDiscovery()
4. 处理SceneDelegate的生命周期问题
- 若使用
SceneDelegate,可将通知注册逻辑移至scene(_:willConnectTo:options:)方法中;同时在页面销毁时注销观察者,避免内存泄漏:override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) NotificationCenter.default.removeObserver(self, name: .GCControllerDidConnect, object: nil) NotificationCenter.default.removeObserver(self, name: .GCControllerDidDisconnect, object: nil) }
5. 测试环境与设备兼容性检查
- 确保使用Apple MFi认证的游戏手柄,非认证设备可能无法触发系统通知。
- 测试前断开手柄与其他设备的蓝牙连接,避免配对冲突。
- 先在iOS系统设置的「蓝牙」中确认手柄已成功连接,再回到App测试通知触发情况。
内容的提问来源于stack exchange,提问作者user20439709
相关产品推荐
相关产品推荐

