2014-02-21 5 views
0

У меня большие проблемы с использованием FSEventStream в моей службе XPC (код ниже). Служба запускается, создается поток, но функция обратного вызова никогда не вызывается. Когда я копирую один и тот же код в основное приложение и запускаю его, он работает отлично. В чем причина того, что он не работает в службе XPC? Я попытался отключить AppSandbox в обеих частях, но ничего не изменил. Любая помощь в этом высоко ценится.Использование FSEventStream в службе XPC не работает

код:

- (void)initEventNotificationStreamForPath:(NSString *)path { 

NPDLOG(@"Starting up FS event listener for path: %@", path); 

NSArray *pathsToWatch = @[path]; 

FSEventStreamContext context; 
context.info = (__bridge void *)self; 
context.version = 0; 
context.retain = NULL; 
context.release = NULL; 
context.copyDescription = NULL; 

NSTimeInterval latency = 1.0; 

_eventStream = FSEventStreamCreate(NULL, &eventNotificationCallback, &context, (__bridge CFArrayRef)pathsToWatch, kFSEventStreamEventIdSinceNow,  //[lastEventID unsignedLongLongValue], 
     (CFAbsoluteTime)latency, (kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagFileEvents | kFSEventStreamCreateFlagWatchRoot)); 

if(_eventStream) { 

    NPDLOG(@"Scheduling event stream on runloop"); 

    FSEventStreamScheduleWithRunLoop(_eventStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); 

    if(!FSEventStreamStart(_eventStream)) { 
     NPDLOG(@"Could NOT start event stream listener!!!"); 
    } 
    else { 

     CFStringRef description = FSEventStreamCopyDescription(_eventStream); 

     NPDLOG(@"Stream description: %@", description); 

     CFRelease(description); 
    } 
} 
else { 
    NPDLOG(@"Could NOT create event stream listener!!!"); 
} 
} 

Моя функция обратного вызова:

void eventNotificationCallback(ConstFSEventStreamRef streamRef, void *userData, size_t numEvents, void *eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]) { 


//[((__bridge NPScannerServiceAgent *)userData).remoteObject didUpdateFilesAtPaths:(__bridge NSArray *)eventPaths]; 

printf("CALLBACK CALLED!!!\n"); 

NSLog(@"GOT FS CHANGE NOTIFICATION FROM %@", (__bridge NPScannerServiceAgent *)userData); 

size_t i; 

for(i = 0; i < numEvents; i++) { 

    NSLog(@"Modified path: %@, flags: %d", [(__bridge NSArray *)eventPaths objectAtIndex: i], eventFlags[i]); 
} 
} 

ответ

1

По умолчанию служба XPC не имеет цикл выполнения. Попробуйте использовать FSEventStreamSetDispatchQueue() вместо FSEventStreamScheduleWithRunLoop(), чтобы функция обратного вызова запускалась в очереди GCD вместо конкретного цикла запуска.

+0

Спасибо за этот отзыв, это действительно интересный момент, о котором я не знал. Попробуй, как только я вернусь к нему. Btw. как получилось, что у XPC нет цикла запуска? Я думал, что когда вызывается метод -resume, он создает собственный цикл запуска, поскольку он никогда не возвращается. – Matthes

+0

Еще один вопрос о добавлении цикла выполнения: http://stackoverflow.com/questions/27806541/using-sockets-with-nsxpcconnection. Суть такова: в вашем info.plist XPC установите 'RunLoopType' в' NSRunLoop' См. Документы Apple для ключей списка свойств службы XPC: https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup /Chapters/CreatingXPCServices.html –

Смежные вопросы