2011-10-13 13 views
11

Recientemente cambié de kqueue a GCD dispatch sources para supervisar los cambios de archivos. Esto funcionó bien y resultó en una API mucho más simple. Documenté mi interruptor here. El único problema que tengo es que ahora no puedo acceder a las banderas en el evento que pude en kqueue. Por ejemplo, con kqueue yo era capaz de comprobar si se ha eliminado el archivo, cambiado de nombre o sus atributos fueron cambiadas con lo siguiente:Indicadores de origen de envío Grand Central Dispatch (GCD)

struct kevent event; 

... 

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

¿Es esta API no está disponible con GCD o tengo que configurar las fuentes de despacho hasta por cada bandera que me gustaría escuchar O es mejor usar kqueue ya que proporciona una mayor visibilidad del evento que ha ocurrido.

+3

No leí tu pregunta, pero la hojeé para que tu reputación sea 1337. Ok, la leeré ahora. – morningstar

Respuesta

8

Encontré la respuesta en el Concurrency Programming Guide. Primero miré en el GCD Reference pero sin suerte. La línea relevante de la guía era

Para una fuente de envío de descriptor que monitorea la actividad del sistema de archivos, esta función devuelve una constante que indica el tipo de evento que ocurrió. Para obtener una lista de constantes, consulte el tipo enumerado dispatch_source_vnode_flags_t.

Aquí hay un ejemplo de cómo puede usarlo.

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

Gracias, eso es increíble. Usé el que está en su [publicación de blog] (http://www.davidhamrick.com/2011/10/13/Monitoring-Files-With-GCD-Being-Edited-With-A-Text-Editor.html). Sin embargo, debe corregir la línea 17 de '[blockSelf watchStyleSheet: path];' a '[blockSelf watchConfigFile: path];'. –

+0

no hay ningún punto para que 'fuente' sea' __block' ya que nunca está asignado a – user102008

3

Puede cambiar * dispatch_source_get_mask (fuente) * a * dispatch_source_get_data (fuente) *, como dispatch_source_get_mask (fuente) devuelve todas las banderas se aprobó en la creación del controlador en lugar del evento generado.

Cuestiones relacionadas