我已成功获得FSEventStream的基础知识,允许我观看新文件事件的文件夹。不幸的是,我传入FSEventStreamCreate()的回调引用正在丢失/损坏/不保留,因此我无法访问我需要的数据对象。这是关键代码块:
FileWatcher.m :(设置FSEvent流)
FSEventStreamContext context;
//context.info = (__bridge_retained void *)(uploadQueue); // this didn't help
context.info = CFBridgingRetain(uploadQueue);
context.version = 0;
context.retain = NULL;
context.release = NULL;
context.copyDescription = NULL;
/* Create the stream, passing in a callback */
stream = FSEventStreamCreate(NULL,
&FileWatcherCallback,
&context,
pathsToWatch,
kFSEventStreamEventIdSinceNow, /* Or a previous event ID */
latency,
kFSEventStreamCreateFlagFileEvents /* Also add kFSEventStreamCreateFlagIgnoreSelf if lots of recursive callbacks */
);
Filewatcher.m:FileWatcherCallback
void FileWatcherCallback(
ConstFSEventStreamRef streamRef,
FSEventStreamContext *clientCallBackInfo,
size_t numEvents,
void *eventPaths,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId eventIds[])
{
int i;
char **paths = eventPaths;
// Retrieve pointer to the download Queue!
NSMutableDictionary *queue = (NSMutableDictionary *)CFBridgingRelease(clientCallBackInfo->info);
// Try adding to the queue
[queue setValue:@"ToDownload" forKey:@"donkeytest" ];
...
}
当触发此回调函数时,我可以很好地获取文件路径,但是指向NSMutableDictionary的clientCallBackInfo-> info指针现在指向与设置流时不同的内存地址。 当我尝试添加到字典中时,我会抛出一个异常(setValue行)。
我是否需要以某种方式处理指针?任何帮助将非常感激。 (我在Xcode 4.5.1上使用默认构建设置,包括ARC。)
答案 0 :(得分:2)
回调函数的第二个参数是void *info
(context.info
),而不是指向FSEventStreamContext context
结构的指针。
所以这段代码应该能够获得正确的指针:
void FileWatcherCallback(
ConstFSEventStreamRef streamRef,
void *info, // <-- this is context.info
size_t numEvents,
void *eventPaths,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId eventIds[])
{
// ...
// Retrieve pointer to the download queue:
NSMutableDictionary *queue = CFBridgingRelease(info);
// ...
}
备注:在我看来,您使用CFBridgingRetain()
/ CFBridgingRelease()
时还有另一个问题。每次调用回调函数时,uploadQueue
对象的保留计数将递减。这会很快导致崩溃。
最好使用
context.info = (__bridge void *)(uploadQueue);
用于创建事件流,
NSMutableDictionary *queue = (__bridge NSMutableDictionary *)info;
在回调函数中。只要使用了事件流,您就必须确保对uploadQueue
保持强引用。
答案 1 :(得分:0)
我从未使用过此API,但是在互联网上查看示例时,在此指针中传递self
似乎很正常。然后,如果uploadQueue
是一个实例变量,您可以通过属性访问它(并且具有访问类实例中所有内容的附加优势)。