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

时间:2015-01-24 11:54:22

标签: macos cocoa events

我尝试监视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();
}

1 个答案:

答案 0 :(得分:2)

Grand Central Dispatch对象(如调度源)在最新版本的编译器和框架中由ARC自动保留和发布。

在您的方法结束时,对source的最后一个强引用将丢失,ARC正在发出自动dispatch_release(source)。 (它也会释放队列,但是源有另一个强引用。所以,如果源存活,队列也会存活。)

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