2011-10-13 93 views
11

我最近从使用kqueue切换到GCD dispatch sources来监视文件更改。这已经很成功,并且导致了一个更简单的API。我记录了我的开关here。我唯一的问题是,现在我无法访问我能够在kqueue中进行的事件。例如用kqueue的,我能够检查文件是否被删除,重命名,或它的属性用以下改变:Grand Central Dispatch(GCD)调度源标记

struct kevent event; 

... 

if(event.flag & EV_DELETE) 
{ 
    printf("File was deleted\n"); 
} 

这是API不具备的GCD还是需要建立调度来源起来为每个我想听的国旗。或者最好使用kqueue,因为它提供了对已发生事件的更高可见性。

+3

我没有真正看过你的问题,但是我把它翻了一番,所以你的声望可以是1337.好的,我现在就读它。 – morningstar

回答

8

我在Concurrency Programming Guide找到了答案。我第一次看到GCD Reference但没有运气。指南中的相关行是

对于监视文件系统活动的描述符调度源,此函数返回一个常数,指示发生的事件类型。有关常量的列表,请参阅dispatch_source_vnode_flags_t枚举类型。

下面是一个如何使用它的例子。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
int fildes = open("path/to/some/file", O_EVTONLY); 
__block 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,^
{ 
    unsigned long flags = dispatch_source_get_mask(source); 
    if(flags & DISPATCH_VNODE_DELETE) 
     printf("DISPATCH_VNODE_DELETE\n"); 
    if(flags & DISPATCH_VNODE_WRITE) 
     printf("DISPATCH_VNODE_WRITE\n"); 
    if(flags & DISPATCH_VNODE_EXTEND) 
     printf("DISPATCH_VNODE_EXTEND\n"); 
    if(flags & DISPATCH_VNODE_ATTRIB) 
     printf("DISPATCH_VNODE_ATTRIB\n"); 
    if(flags & DISPATCH_VNODE_LINK) 
     printf("DISPATCH_VNODE_LINK\n"); 
    if(flags & DISPATCH_VNODE_RENAME) 
     printf("DISPATCH_VNODE_RENAME\n"); 
    if(flags & DISPATCH_VNODE_REVOKE) 
     printf("DISPATCH_VNODE_REVOKE\n"); 
}); 
dispatch_source_set_cancel_handler(source, ^(void) 
{ 
    close(fildes); 
}); 
dispatch_resume(source); 
+0

谢谢,这真是太棒了。我在你的[博客文章]上使用了一个(http://www.davidhamrick.com/2011/10/13/Monitoring-Files-With-GCD-Being-Edited-With-A-Text-Editor.html)。但是,您应该将行17从'[blockSelf watchStyleSheet:path];'更正为'[blockSelf watchConfigFile:path];''。 –

+0

'source'是'__block'没有意义,因为它永远不会被分配给 – user102008

3

你可以改变* dispatch_source_get_mask(源)*为* dispatch_source_get_data(源)*,为dispatch_source_get_mask(源)返回您在创建处理程序,而不是生成的事件通过了所有的标志。

相关问题