2013-10-31 27 views
0

我正在使用FSEvents來監視一個目錄,並且每當目錄發生變化時,我調用一個塊,我最初傳入FSEventStreamRef的FSEventStreamContext。如何在需要停止監視目錄時釋放該塊?以下代碼供參考。OS X和FSEvents:如何釋放提供給FSEventStreamRef的回調指針?

void fsevents_callback(ConstFSEventStreamRef streamRef, void *clientCallBackInfo, size_t numEvents, void *eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]) { 
    void (^block)() = (__bridge void (^)())(clientCallBackInfo); 
    block(); 
} 

- (FSEventStreamRef)startObserving:(NSString *)path block:(void(^)())block { 
    void *ptr = (void *)CFBridgingRetain(block); // NOTE: the block is retained 
    FSEventStreamContext context = { 0, ptr, NULL, NULL, NULL }; 
    FSEventStreamRef stream = FSEventStreamCreate(NULL, fsevents_callback, &context, (__bridge CFArrayRef)@[path], kFSEventStreamEventIdSinceNow, 10, kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagIgnoreSelf); 
    FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetMain(), kCFRunLoopDefaultMode); 
    FSEventStreamStart(stream); 
    return stream; 
} 

- (void)stopObserving:(FSEventStreamRef)stream { 
    // HELP: the block should be released here. can I get it through FSEvents? 
    FSEventStreamStop(stream); 
    FSEventStreamInvalidate(stream); 
    FSEventStreamRelease(stream); 
} 
+0

您不需要釋放塊;至少我從未見過它。 – trojanfoe

回答

0

FSEventStreamContext具有成員變量函數保留和釋放info指針,它在你的例子是您的void *塊指針。

通過Apple's FSEvents reference

retain 
    The callback used retain the info pointer. This can be NULL. 

release 
    The callback used release a retain on the info pointer. This can be NULL. 

首先,保留。由於您無論如何都需要將代碼塊轉換爲void *代碼FSEventStreamContext,我認爲在您的startObserving:方法中繼續使用CFBridgingRetain()是很好的做法。不需要保留回調函數。

發佈,試試這個回調函數:

void release_callback(const void *info) { 
    CFBridgingRelease(info); 
} 

然後試着改變你的FSEventStreamContext聲明:

FSEventStreamContext context = { 0, ptr, NULL, release_callback, NULL }; 

應當釋放你的塊時stopObserving:被調用。

+0

謝謝!我完全沒有注意FSEventStreamContext的這兩個變量。 – Steveo

+0

所以,大家好,請你告訴我代碼如何釋放? – Sid