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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 08:45:32