objective-c – 使用Grand Central Dispatch进行文件监控

我使用 David Hamrick代码示例来使用GCD监视文件.

int fildes = open("/path/to/config.plist",O_RDONLY);

dispatch_queue_t queue = dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_source_t source = dispatch_source_create(disPATCH_SOURCE_TYPE_VNODE,fildes,disPATCH_VNODE_DELETE | disPATCH_VNODE_WRITE | disPATCH_VNODE_EXTEND | disPATCH_VNODE_ATTRIB | disPATCH_VNODE_LINK | disPATCH_VNODE_RENAME | disPATCH_VNODE_REVOKE,queue);
dispatch_source_set_event_handler(source,^
{
    //Reload the config file
});
dispatch_source_set_cancel_handler(source,^
{
    //Handle the cancel
});
dispatch_resume(source);

我想用来监视一个plist的变化.我在第一次更改后收到通知,但没有收到以下更改.为什么?

解决方法

您确实可以在收到disPATCH_VNODE_DELETE时重新打开文件并重新注册源(删除一个).或者您可以使用专为此类场景设计的调用,即dispatch_io_create_with_path() – 它不仅会按路径观看,还会为您打开文件并让您以异步方式读取内容.

既然你问(不知道你要求哪种技术,但这里最简单)这里有一个独立的代码示例:

#include <dispatch/dispatch.h>
#include <stdio.h>

int main(int ac,char *av[])
{
  int fdes = open("/tmp/pleasewatchthis",O_RDONLY);
  dispatch_queue_t queue = dispatch_get_global_queue(0,0);
  void (^eventHandler)(void),(^cancelHandler)(void);
  unsigned long mask = disPATCH_VNODE_DELETE | disPATCH_VNODE_WRITE | disPATCH_VNODE_EXTEND | disPATCH_VNODE_ATTRIB | disPATCH_VNODE_LINK | disPATCH_VNODE_RENAME | disPATCH_VNODE_REVOKE;
  __block dispatch_source_t source;

  eventHandler = ^{
    unsigned long l = dispatch_source_get_data(source);
    if (l & disPATCH_VNODE_DELETE) {
      printf("watched file deleted!  cancelling source\n");
      dispatch_source_cancel(source);
    }
    else {
      // handle the file has data case
      printf("watched file has data\n");
    }
  };
  cancelHandler = ^{
    int fdes = dispatch_source_get_handle(source);
    close(fdes);
    // Wait for new file to exist.
    while ((fdes = open("/tmp/pleasewatchthis",O_RDONLY)) == -1)
      sleep(1);
    printf("re-opened target file in cancel handler\n");
    source = dispatch_source_create(disPATCH_SOURCE_TYPE_VNODE,fdes,mask,queue);
    dispatch_source_set_event_handler(source,eventHandler);
    dispatch_source_set_cancel_handler(source,cancelHandler);
    dispatch_resume(source);
  };

  source = dispatch_source_create(disPATCH_SOURCE_TYPE_VNODE,queue);
  dispatch_source_set_event_handler(source,eventHandler);
  dispatch_source_set_cancel_handler(source,cancelHandler);
  dispatch_resume(source);
  dispatch_main();
}

相关文章

我正在用TitaniumDeveloper编写一个应用程序,它允许我使用Ja...
我的问题是当我尝试从UIWebView中调用我的AngularJS应用程序...
我想获取在我的Mac上运行的所有前台应用程序的应用程序图标....
我是一名PHP开发人员,我使用MVC模式和面向对象的代码.我真的...
OSX中的SetTimer在Windows中是否有任何等效功能?我正在使用...
我不确定引擎盖下到底发生了什么,但这是我的设置,示例代码和...