objective-c – 在FSEventStream回调(ObjC和ARC)中丢失指针
发布时间:2020-12-16 07:33:49 所属栏目:百科 来源:网络整理
导读:我已成功获得FSEventStream的基础知识,允许我查看新文件事件的文件夹.不幸的是,我传入FSEventStreamCreate()的回调引用正在丢失/损坏/不保留,因此我无法访问我需要的数据对象.这是关键代码块: FileWatcher.m :(设置FSEvent流) FSEventStreamContext context
我已成功获得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指针现在指向与设置流时不同的内存地址. 我是否需要以某种方式处理指针?任何帮助将非常感激. 解决方法
回调函数的第二个参数是void * info(它是context.info),而不是指向FSEventStreamContext上下文结构的指针.
所以这段代码应该能够获得正确的指针: void FileWatcherCallback( ConstFSEventStreamRef streamRef,void *info,// <-- this is context.info size_t numEvents,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保持强引用. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |