【问题标题】:OS X and FSEvents: How do you release a callback pointer supplied to an FSEventStreamRef?OS X 和 FSEvents:如何释放提供给 FSEventStreamRef 的回调指针?
【发布时间】:2013-10-31 17:01:01
【问题描述】:

我正在使用 FSEvents 来监视一个目录,并且每当目录更改时,我都会调用一个块,该块我最初传递到 FSEventStreamRef 的 FSEventStreamContext 中。在停止监视目录时如何释放块?下面的代码供参考。

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);
}

【问题讨论】:

  • 你不需要释放块;至少我没见过。

标签: callback objective-c-blocks fsevents toll-free-bridging


【解决方案1】:

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 * for FSEventStreamContext,我认为在您的startObserving: 方法中继续使用CFBridgingRetain() 是可以的。不需要保留回调函数。

要发布,试试这个回调函数:

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

然后尝试将您的 FSEventStreamContext 声明更改为:

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

stopObserving: 被调用时应该会释放你的块。

【讨论】:

  • 谢谢!我完全没有注意FSEventStreamContext的这两个变量。
  • 各位,请告诉我代码是怎么去那里发布的??
猜你喜欢
  • 2013-11-13
  • 2019-05-11
  • 2011-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-07
  • 2019-02-22
  • 2011-01-30
相关资源
最近更新 更多