【问题标题】:What happens when an object using ARC contains multiple non-ARC objects?当使用 ARC 的对象包含多个非 ARC 对象时会发生什么?
【发布时间】:2013-09-18 13:18:59
【问题描述】:

我有一个使用 ARC 的 A 类和其他不使用的 B 和 C 类。如果 A 包含 B 类对象,B 包含 C 类对象,那么 ARC 是如何工作的?如果在 B 类和 C 类中没有正确处理内存管理会发生什么?

【问题讨论】:

  • 一切正常。 ARC 并不是什么魔法,它只是编译器为您插入保留/释放。它可以很好地与非 ARC 代码集成。
  • 由于A类有ARC,所以它会释放你创建的对象。它不会释放有保留周期的对象,而B类和c类没有弧,所以你必须手动释放您创建的所有对象。

标签: ios objective-c automatic-ref-counting


【解决方案1】:

我同意 Mike 和 Martin 的观点,即 ARC 类中的非 ARC 对象的集成通常是无缝进行的(假设您已将 -fno-objc-arc 编译标志添加到那些不是 ARC 或位于使用手动引用计数编译的库)。

需要注意的是,ARC 依赖于符合Basic Memory Management Rules 中列出的方法命名规则的代码。因此,您的非 ARC 代码必须遵守这些方法命名规则,否则 ARC 可能无法正确处理生成的对象。如果非 ARC 代码遵循长期存在的方法命名约定(以 allocnewcopymutableCopy 开头的方法将返回 +1 对象,否则从方法将是autorelease 对象),所以这通常不是问题。但是如果你的非 ARC 代码不遵循这个方法命名约定,但是在将这个非 ARC 代码与你的 ARC 类集成时,它可能会成为内存管理的绊脚石。

如果非 ARC 代码不符合这些命名约定,您要么必须重命名方法,更正代码的内存管理以对应方法名称,要么在代码不符合的地方为编译器提供提示遵守这些方法命名规则(例如NS_RETURNS_RETAINEDNS_RETURNS_NOT_RETAINED)。

【讨论】:

    【解决方案2】:

    ARC 所做的是查看您的代码并假设您的对象应该在哪里释放、自动释放等。在编译时,所有的保留、释放、retainCount、自动释放或释放方法都将添加到您的代码中。这使您的非弧码与您的弧码完全兼容。

    至于内存管理不当,请尝试在构建时使用静态分析器以获取尽可能多的错误。

    希望这会有所帮助,干杯!

    【讨论】:

    • 这些“假设”基于"Basic Memory Management Rules" 中描述的所有权命名约定,因此非ARC 代码必须严格遵守这些约定。但你是对的,静态分析器会检查这一点。
    • @MartinR 同意,尽管静态分析器没有发现(所有)失败符合非 ARC 代码中的命名约定。它的工作非常出色,但有些故障仅表现为 Instruments 中的泄漏。
    猜你喜欢
    • 2014-06-19
    • 2012-12-19
    • 2015-11-07
    • 2012-05-04
    • 2017-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多