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

Macos 来自调度队列的OSX 10.10文件更改事件,macos,cocoa,events,Macos,Cocoa,Events,我尝试在OSX 10.10上监视文件更改,从Xcode中的新Cocoa应用程序开始,只添加以下代码 如果我取消注释代码段中的最后一行,那么我将很好地接收文件更改事件。但我不能进行最后一次调用,因为它应该是一个Cocoa GUI应用程序 我翻了很多文档,找不到我的错误。我是否必须以某种方式初始化或启动整个调度子系统 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { int fd = open("<

我尝试在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();
}
-(无效)应用程序设计完成启动:(NSNotification*)通知{
int fd=打开(“,O_EVTONLY”);
如果(fd==-1)返回;
dispatch\u queue\u t qu=dispatch\u get\u global\u queue(dispatch\u queue\u PRIORITY\u DEFAULT,0);
如果(!qu){
printf(“无法获取队列”);
返回;
}
无符号长掩码=
分派_VNODE _删除|
发送VNODE写入|
调度节点扩展|
调度节点属性|
调度节点链接|
调度\u VNODE\u重命名|
调度节点撤销;
dispatch\u source\u t source=dispatch\u source\u create(dispatch\u source\u TYPE\u VNODE,fd,mask,qu);
printf(“创建的源代码”);
如果(!源){
关闭(fd);
返回;
}
printf(“源有效\n”);
调度\u源\u集\u事件\u处理程序(源^{
printf(“文件更改\n”);
});
发送简历(来源);
printf(“源恢复\n”);
//如果调用dispatch_main(),我将按预期接收文件系统事件。
//但作为一个可可应用程序,我不能称之为。
//相反,我的印象是NapplicationMain处理这个问题。
//调度_main();
}

在最新版本的编译器和框架中,ARC会自动保留和发布Grand Central分派对象,例如分派源

在方法结束时,对
源代码的最后一个强引用将丢失,ARC将发出自动
调度发布(源代码)
。(它也会释放队列,但源有另一个对该队列的强引用。因此,如果源幸存,那么队列也会如此。)

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