objective-c - 无法访问的对象在变得无法访问后是否随时都可以安全地收集?

标签 objective-c cocoa garbage-collection objective-c++

我将一些 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/

相关文章:

objective-c - Cocoa:在 Controller 中的windowDidLoad中获取窗口

objective-c - 在 Cocoa 命令行程序中运行 NSRunLoop

c# - 拥有一次性字段的类型应该是一次性的。如何解决这个警告?

objective-c - 为什么我们在 Objective C 中通常导入 .h 文件而不导入 .m 文件?

ios - Objective-C - 如何知道点是否在四分之一圆内?

objective-c - 无法从 NSTask 的标准输出获取中间输出?

garbage-collection - 生成的 C 中的高效 GC 写入屏障

java - 堆转储中不可能的 Java 内存引用

ios - 如何在自定义 View 中使用选择器

ios - 如何在我的代码中添加循环