SCShareableContent.getExcludingDesktopWindows偶不调用完成处理程序求助
解决思路
针对你遇到的SCShareableContent.getExcludingDesktopWindows偶尔不触发完成回调的问题,可从以下几个方向排查:
1. 排查队列与任务阻塞问题
你的videoSampleQueue是默认创建的串行队列,若队列中存在未完成的阻塞任务(比如processContent里有同步耗时操作),会导致后续的捕获请求被挂起。建议:
- 确保
processContent中的耗时操作被调度到其他队列执行,不要阻塞videoSampleQueue; - 调用
getExcludingDesktopWindows前,可通过自定义计数方式记录队列任务量,确认是否存在任务堆积情况。
2. 验证ScreenCaptureKit的权限与系统状态
ScreenCaptureKit的行为受系统权限和资源状态直接影响:
- 每次调用前调用
SCShareableContent.isCaptureAvailable(),捕获并记录返回值,排查是否存在权限临时失效的情况; - 监听
SCScreenCaptureStateChanged通知,实时获取屏幕捕获状态变化,看问题出现时是否有状态异常; - 监控系统CPU、内存资源使用情况,若问题出现时系统资源耗尽,可能是系统暂停了ScreenCaptureKit的回调。
3. 添加超时兜底机制
系统API无法保证100%触发回调,给捕获请求添加超时处理,避免任务永久挂起:
videoSampleQueue?.async { NSLog("Inside video queue") let timeoutInterval: TimeInterval = 3 var timeoutTask: DispatchWorkItem? timeoutTask = DispatchWorkItem { NSLog("Shareable content capture timed out") captureCompletion?(nil, NSError(domain: "CaptureError", code: -1001, userInfo: [NSLocalizedDescriptionKey: "获取共享内容超时"])) } DispatchQueue.global().asyncAfter(deadline: .now() + timeoutInterval, execute: timeoutTask!) SCShareableContent.getExcludingDesktopWindows(true, onScreenWindowsOnly: false, completionHandler: { [weak self] content, error in timeoutTask?.cancel() NSLog("Shareable content received") self?.processContent(content, error, captureCompletion) }) }
4. 增强日志与调试
- 给
startCapture添加调用计数日志,记录每次调用的序号,出现问题时对比序号和系统状态,寻找潜在规律; - 在回调中同时打印
content和error的具体值(即使看起来没触发,也可能是日志输出被吞); - 使用Xcode的调试导航栏查看
videoSampleQueue的任务栈,若问题出现时暂停应用,检查队列是否有未执行的任务。
5. 版本兼容性排查
当前使用的Xcode 14.2和macOS 13.3.1可能存在ScreenCaptureKit的已知bug,建议升级到最新版本的Xcode和macOS,查看Apple官方release notes,确认是否有相关的回调修复。
内容的提问来源于stack exchange,提问作者Ross Stepaniak
相关产品推荐
相关产品推荐

