我将一些 Obj-C 对象存储在 C++ 数据结构中。由于我在垃圾收集下运行并且我的对象只能通过 C++ 结构访问,我正在调用 CFRetain() 来根化添加到结构中的每个对象,以确保它们不会被过早收集:
- (void) doSomethingFancyWithObjects:(NSArray*)array
{
std::list<NSObject*> list;
for (NSObject* obj in array)
{
id copyAddedToList = [obj copy];
list.push_back(copyAddedToList);
CFRetain(copyAddedToList); // otherwise list.back() becomes unreachable...
}
// ... //
BOOST_FOREACH(NSObject* obj, list)
{
CFRelease(obj);
}
}
有必要这样做吗? GC 是否真的有可能在无法访问的方法中启动并收集无法访问的对象? GC 可以随时收集,还是仅在特定时间(例如 run loop 结束)收集?还没有设法找到与此相关的文档。
最佳答案
正如在您的代码中发布的那样,所有事情都发生在 doSomethingFancyWithObjects:
范围内,您不需要 CFRetain/CFRelease
对,因为您没有从 array
位于堆栈中,因此是 Root过的。
编辑
好的,我没有正确阅读代码 - 正在复制对象。
首先,我质疑复制的必要性。如果您正在修改列表中的对象,为什么?他们在最后被扔掉了。
其次,你实际上有一个竞争条件。垃圾收集器可以在 list.push_back([obj copy]);
和 CFRetain(list.back());
之间,然后 中的对象指针>std::list
将悬空。你应该这样做:
NSObject* theCopy = [obj copy];
CFRetain(theCopy);
list.push_back(theCopy);
关于objective-c - 无法访问的对象在变得无法访问后是否随时都可以安全地收集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5835310/