OSX 10.10 来自调度队列的文件更改事件

OSX 10.10 file change event from dispatch queue

我尝试在 OSX 10.10 上监控文件更改,从 Xcode 中的新 Cocoa 应用程序开始,只需添加以下代码。

如果我取消注释代码段中的最后一行,那么我会很好地接收文件更改事件。但我无法进行最后一次调用,因为它应该是一个 Cocoa GUI 应用程序。

我翻阅了大量文档,但找不到我的错误。我是否必须以某种方式初始化或启动整个调度子系统?

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
  int fd = open("<FILENAME>", O_EVTONLY);
  if (fd == -1) return;
  dispatch_queue_t qu = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  if (!qu) {
    printf("can not get queue");
    return;
  }
  unsigned long mask =
    DISPATCH_VNODE_DELETE |
    DISPATCH_VNODE_WRITE |
    DISPATCH_VNODE_EXTEND |
    DISPATCH_VNODE_ATTRIB |
    DISPATCH_VNODE_LINK |
    DISPATCH_VNODE_RENAME |
    DISPATCH_VNODE_REVOKE;
  dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fd, mask, qu);
  printf("source created\n");
  if (!source) {
    close(fd);
    return;
  }
  printf("source valid\n");
  dispatch_source_set_event_handler(source, ^{
    printf("FILE CHANGED\n");
  });
  dispatch_resume(source);
  printf("source resumed\n");

  // If I call dispatch_main() I will receive the file system events as expected.
  // But as a Cocoa application, I must not call this.
  // Instead, I was under the impression that NSApplicationMain handles this.
  //dispatch_main();
}

Grand Central Dispatch 对象,例如调度源,在最新版本的编译器和框架中由 ARC 自动保留和释放。

在您的方法结束时,对 source 的最后一个强引用丢失并且 ARC 发出自动 dispatch_release(source)。 (它也会释放队列,但源对此有另一个强引用。因此,如果源幸存下来,队列也会。)

您需要在实例变量中保持对源的强引用。