【问题标题】:Best practice for assigning new objects to retained properties?将新对象分配给保留属性的最佳实践?
【发布时间】:2010-12-15 18:42:25
【问题描述】:

我正在为我的 iPhone 应用程序使用 Core Data。我的属性是使用保留属性设置的。

例如,“事物”实体中的“数字”属性:

#import <CoreData/CoreData.h>

@interface Thing :  NSManagedObject  
{
}
@property (nonatomic, retain) NSNumber * number;
@end

@implementation Thing 
@dynamic number;
@end

在我的代码中使用 Thing 对象时,我一直在设置 number 属性,如下所示:

thing.number = [[NSNumber alloc] initWithInteger:1];

但是,这会造成内存泄漏(新的 NSNumber 对象的保留计数由于 alloc plus 属性保留而比期望的高一)。

由于这是针对 iPhone 操作系统的,我想自己管理内存,所以我选择不使用自动释放池(它还有更好的性能和更低的最大内存使用量的好处)。

  1. 我知道这种模式有效(并且已经在几篇 SO 帖子中讨论过):

    NSNumber *num = [[NSNumber alloc] initWithInteger:1];
    thing.number = num;
    [num release];
    

    这个模式很清楚,但是我对三行或临时变量并不感到兴奋。

  2. 我认为这也会起作用(但我没有在任何 SO 帖子上注意到它):

     thing.number = [[NSNumber alloc] initWithInteger:1];
     [thing.number release];
    

    这种模式不太清楚,但只需要两行并且不使用临时变量。

问题
是否有任何其他模式可以将新对象分配给保留属性(不使用自动释放池)?这里的最佳做法是什么?

【问题讨论】:

    标签: iphone memory-management core-data properties cocoa-design-patterns


    【解决方案1】:

    除了使用自动释放池之外,这些是我唯一见过的。我不会警惕自动释放。它们工作得很好,在这种情况下您可能看不到任何性能差异。

    但是,如果您真的想避免这种情况,这里适用的最佳实践似乎是“最小意外原则”。由于在大多数示例代码中都可以找到第一个习语,因此您似乎应该为了维护代码的人而吸收额外的行。

    【讨论】:

    • 我的意图是避免将其变成关于自动释放的讨论(在我看来,关于 SO 的讨论已经足够多)。关于“原则”的好点,但我会坚持这一点,所以任何一种方法都应该有效。
    【解决方案2】:

    无论您是否使用它们,默认情况下自动释放池已经围绕您的代码。就我个人而言,如果您不使用自动释放的对象,我认为您不会获得更好的性能。请记住,自动释放池和垃圾收集是两个不同的概念,前者要简单得多。唯一不想使用自动释放对象的地方是大循环。

    作为记录,第二种模式也应该可以正常工作。

    【讨论】:

    • 我的意图是避免将其变成关于自动释放的讨论(在我看来,关于 SO 的讨论已经足够多)。我同意我的应用程序几乎肯定没有问题,即使我的核心数据属性广泛使用自动释放对象。 +1 供您考虑。
    【解决方案3】:

    除非您在紧密循环中创建大量对象,否则自动释放池不应使用更​​多内存。

    我猜你的选择是要么使用你需要编写的 2 或 3 行代码,要么只使用自动释放池。

    就个人而言,除非遇到特定的性能或内存问题,否则我肯定会使用自动释放池。

    【讨论】:

    • 我的意图是避免将其变成关于自动释放的讨论(在我看来,关于 SO 的讨论已经足够多)。我同意我的应用程序几乎肯定没有问题,即使我的核心数据属性广泛使用自动释放对象。
    【解决方案4】:

    对于许多对象,您可以直接使用返回自动释放实例的方法。例如,我通常将您的代码 sn-p 编写如下:

    thing.number = [NSNumber numberWithInt:1];

    请注意,由于您的属性保留了 NSNumber,因此您需要稍后在使用完该属性后释放它。

    无论如何,当这不适用时,因为您没有构造函数返回自动释放的对象,您的模式 1 绝对是正确的。

    相反,在我看来,模式 2 不正确,原因如下:您首先将 NSNumber 分配给您的财产,然后释放您的财产。但是,您需要释放您分配的 NSNumber,而不是您的财产保留的那个(稍后您将这样做,当您完成财产时再次这样做)。模式 2 的最终结果应该是内存泄漏(分配的 NSNumber 未释放)并且您的属性不包含 NSNumber(因为您首先保留它然后释放它)。

    【讨论】:

    • 对于模式 2,仍然只有一个对象,并且它的保留计数适当减少。请记住:对象的引用(指针)没有保留计数,对象有保留计数。
    • 好的,这是有道理的。是否有任何 Apple 文档更详细地讨论此问题?提前感谢您分享此内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 2011-12-27
    • 1970-01-01
    • 2019-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多