关于ICDeviceBrowser退出重进页面后无法检测相机的技术咨询
问题解决:ICDeviceBrowser退出页面重进后无法检测相机设备
问题原因分析
- 异步资源清理逻辑不严谨:原代码在
viewWillDisappear中用固定0.5秒延迟销毁浏览器,但requestCloseSession是异步操作,固定延迟无法保证会话真正关闭就清理资源,导致设备状态未正确释放,下次启动浏览器时系统判定设备仍被占用。 - 设备检查时机不可靠:
viewDidAppear里用1秒延迟读取browser.devices,但浏览器启动后需要时间完成设备枚举,此时数组可能还未填充设备信息。 - 设备移除回调逻辑缺失:原
didRemoveDevice回调未针对当前绑定的相机设备做精准清理,可能残留无效引用。
修复方案
1. 调整会话与浏览器的销毁时机,依赖回调而非固定延迟
将浏览器的停止与资源清理逻辑移到didCloseSessionWithError回调中,确保会话真正关闭后再清理资源:
- (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; if (@available(iOS 13.0, *)) { if (self.cameraDevice) { if (self.cameraDevice.hasOpenSession) { [self.cameraDevice requestCloseSession]; } else { self.cameraDevice.delegate = nil; self.cameraDevice = nil; [self cleanupBrowser]; } } else { [self cleanupBrowser]; } } else { // Fallback on earlier versions } } // 新增浏览器清理方法 - (void)cleanupBrowser { if (@available(iOS 13.0, *)) { if (self.browser) { [self.browser stop]; self.browser.delegate = nil; self.browser = nil; } } } // 修改会话关闭回调,完成资源清理 - (void)device:(ICDevice*)device didCloseSessionWithError:(NSError* _Nullable)error API_AVAILABLE(ios(13.0)){ if (error) { NSLog(@"close session error = %@",error.localizedDescription); } else { NSLog(@"didCloseSession"); } if (@available(iOS 13.0, *)) { self.cameraDevice.delegate = nil; self.cameraDevice = nil; [self cleanupBrowser]; } }
2. 优化设备枚举逻辑,确保重进时能触发设备检测
在浏览器启动后主动调用refresh,强制枚举已连接的设备:
- (void)addImageCaptureCore { if (@available(iOS 13.0, *)) { ICDeviceBrowser *browser = [[ICDeviceBrowser alloc] init]; browser.delegate = self; [browser start]; self.browser = browser; // 主动刷新设备列表,确保已连接设备被枚举 [browser refresh]; } }
同时,调整设备检查逻辑,确保浏览器运行时再读取设备列表:
- (void)checkCameraConnection { if (@available(iOS 13.0, *)) { if (self.browser.isRunning) { NSArray<ICDevice *> *connectedDevices = self.browser.devices; NSLog(connectedDevices.count > 0 ? @"Camera is connected" : @"Camera is not connected"); } } }
3. 修复设备移除回调的精准处理
确保设备移除时只清理当前绑定的相机设备:
- (void)deviceBrowser:(ICDeviceBrowser*)browser didRemoveDevice:(ICDevice*)device moreGoing:(BOOL) moreGoing API_AVAILABLE(ios(13.0)){ if ([device isEqual:self.cameraDevice]) { if (self.cameraDevice.hasOpenSession) { [self.cameraDevice requestCloseSession]; } else { self.cameraDevice.delegate = nil; self.cameraDevice = nil; } } }
验证要点
- 退出页面时,控制台需输出
didCloseSession,确认会话已正确关闭 - 重进页面后,
didAddDevice回调需被触发并输出设备名称 - 调用
checkCameraConnection时能正确识别已连接的相机设备
内容的提问来源于stack exchange,提问作者王超峰
相关产品推荐
相关产品推荐

