2012-07-12 77 views

回答

6

我無法找到一個簡單的例子,所以我參與我想出了以供將來參考:

@interface FileWatch() 
@property(assign) dispatch_source_t source; 
@end 

@implementation FileWatch 
@synthesize source; 

- (id) initWithPath: (NSString*) path targetQueue: (dispatch_queue_t) queue block: (dispatch_block_t) handler 
{ 
    self = [super init]; 

    int descriptor = open([path fileSystemRepresentation], O_EVTONLY); 
    if (descriptor < 0) { 
     return nil; 
    } 

    [self setSource:dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, descriptor, DISPATCH_VNODE_WRITE, queue)]; 
    dispatch_source_set_event_handler(source, handler); 
    dispatch_source_set_cancel_handler(source, ^{ 
     close(descriptor); 
    }); 

    dispatch_resume(source); 
    return self; 
} 

- (void) dealloc 
{ 
    if (source) { 
     dispatch_source_cancel(source); 
     dispatch_release(source); 
     source = NULL; 
    } 
} 

@end 
+0

參見:http://stackoverflow.com/questions/11355144/file-monitoring-using-grand-central-dispatch/11372441#11372441 - 這只是想出最近。 :) – jkh 2012-07-12 19:04:28

+0

會很好,如果你可以描述代碼做的評論在那裏:/ – 2015-06-07 06:24:35

2

從我的實際經驗,在某些情況下,文件不僅被寫入但隨後被刪除重寫(一些plist文件的情況)。然後,您必須稍微調整代碼:在ordre中替換文件時再次調用該方法以保持監視。

- (void) myMonitoringMethodWithPath: :(NSString*) path 
     __block typeof(self) blockSelf = self; 
     __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_data(source); 
              //Do some stuff 

              if(flags & DISPATCH_VNODE_DELETE) 
              { 
               [blockSelf myMonitoringMethodWithPath:path]; 

              } 
             }); 
    dispatch_source_set_cancel_handler(source, ^(void) 
             { 
              close(fildes); 
             }); 
    dispatch_resume(source); 
}