2014-02-21 2 views
0

내 XPC 서비스에서 FSEventStream을 사용하는 데 큰 문제가 있습니다 (아래 코드). 서비스가 시작되고 스트림이 생성되지만 콜백 함수는 호출되지 않습니다. 내 응용 프로그램에 정확히 동일한 코드를 복사하고 실행하면 정상적으로 작동합니다. XPC 서비스에서 작동하지 않는 이유는 무엇입니까? AppSandbox를 두 부분에서 모두 비활성화하려고했지만 아무 것도 변경하지 않았습니다. 어떤 도움을 주셔서 감사합니다.XPC 서비스 내에서 FSEventStream을 사용할 수 없습니다.

코드 :

- (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 서비스가 실행 루프를 가지고 있지 않습니다. FSEventStreamScheduleWithRunLoop() 대신 FSEventStreamSetDispatchQueue()을 사용하여 특정 실행 루프가 아닌 GCD 대기열에서 콜백 함수가 트리거되도록하십시오.

+0

이 팁을 보내 주셔서 감사합니다. 내가 그걸로 돌아 가자 마자 시도 할께. Btw. 어떻게 XPC에 러닝 루프가없는 걸까요? -resume 메서드가 호출되면 절대 반환하지 않는 자체 실행 루프를 생성한다고 생각했습니다. – Matthes

+0

실행 루프 추가에 관한 또 다른 질문 : http://stackoverflow.com/questions/27806541/using-sockets-with-nsxpcconnection. 요지는 XPC의 info.plist에서'RunLoopType'을'NSRunLoop'으로 설정합니다. XPC 서비스 속성 목록 키에 대한 Apple의 문서를 참조하십시오 : https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup /Chapters/CreatingXPCServices.html –

관련 문제