代码之家  ›  专栏  ›  技术社区  ›  gerry3

将新对象分配给保留属性的最佳实践?

  •  1
  • gerry3  · 技术社区  · 15 年前

    我正在为我的iPhone应用程序使用核心数据。我的属性是用保留属性设置的。

    例如,“thing”实体中的“number”属性:

    #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];
    

    但是,这会造成内存泄漏(由于alloc plus属性retain,新nsnumber对象的保留计数比所需的高一个)。

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

    1. 我知道这个模式是可行的(已经在几个这样的帖子中讨论过了):

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

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

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

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

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

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

    4 回复  |  直到 15 年前
        1
  •  3
  •   Benjamin Cox    15 年前

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

    然而,如果你真的想避免这种情况,这里的最佳实践似乎是“最不令人惊讶的原则”。因为第一个习语在大多数示例代码中都有,所以似乎您应该为了维护代码的人而把多余的行占用掉。

        2
  •  2
  •   Mihai Damian    15 年前

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

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

        3
  •  1
  •   Thomas Müller    15 年前

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

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

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

        4
  •  1
  •   Massimo Cafaro    15 年前

    对于许多对象,可以直接使用返回自动释放实例的方法。作为一个例子,我通常编写与您的代码片段等效的代码段,如下所示:

    thing.number=[nsnumber numberWithint:1];

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

    无论如何,如果这不适用,因为没有构造函数返回自动释放的对象,那么模式1肯定是正确的。

    相反,模式2在我看来是不正确的,原因如下:首先将nsnumber分配给您的属性,然后释放您的属性。但是,您需要释放已分配的nsnumber,而不是由您的属性保留的nsnumber(稍后您将执行此操作,在完成该属性后再次执行此操作)。模式2的净效果应该是内存泄漏(分配的nsnumber没有释放),而您的属性不包含nsnumber(因为您首先保留它,然后释放它)。