使用DispatchSource.makeFileSystemObjectSource()监听文件无事件触发问题
问题:Dispatch Source监听文件变更无事件回调
我参考了一篇关于监听文件变更的文章,按照指引创建了Dispatch Source,但从未收到任何事件。我已经将eventMask设置为.all,尝试了多种修改文件的方式(BBEdit/TextEdit编辑保存、vim命令行编辑、echo "test" >> myfile.txt),每次测试前都会重启应用获取新文件句柄,但事件处理程序始终无响应。代码如下:
override func viewDidAppear() { super.viewDidAppear() Task { self.configurl = await self.openfile(forkey: self.keybookmarkconfig) if let url = self.configurl { print("creating filehandle for \(url.absoluteString)") self.configfilehandle = try FileHandle(forReadingFrom: url) print("creating dispatch source to watch \(url.absoluteString)") self.source = DispatchSource.makeFileSystemObjectSource( fileDescriptor: self.configfilehandle.fileDescriptor, eventMask: .all, queue: DispatchQueue.main ) print("setting event handler for dispatch source") self.source.setEventHandler { print("config file changed") } print("done with watcher setup") } } }
核心问题:未启动Dispatch Source
Dispatch Source对象创建后默认处于暂停状态,必须调用resume()方法才能开始监听事件,这是你遗漏的关键步骤。
修复代码
在设置完事件处理器后添加启动代码:
print("setting event handler for dispatch source") self.source.setEventHandler { print("config file changed") } // 新增:启动Dispatch Source self.source.resume() print("done with watcher setup")
额外注意事项
- 编辑器文件替换问题:BBEdit、TextEdit这类编辑器保存时会删除原文件并重建新文件,此时原文件句柄会失效。你可以改为监听文件所在目录,或者在收到文件删除事件后重新创建对新文件的监听。
- 对象生命周期:确保
configfilehandle和source作为类属性被持有,避免被ARC提前释放导致监听失效。 - 权限验证:确认应用对目标文件有读取权限,尤其是沙箱环境下的文件需要正确配置权限。
内容的提问来源于stack exchange,提问作者Kenny Wyland
相关产品推荐
相关产品推荐

