代码之家  ›  专栏  ›  技术社区  ›  Ronnie Liew

对象C中的对象分配和初始化

  •  56
  • Ronnie Liew  · 技术社区  · 16 年前

    以下两种分配和初始化对象的方法有什么区别?

    AController *tempAController = [[AController alloc] init];
    self.aController = tempAController;
    [tempAController release];
    

    self.aController= [[AController alloc] init];
    

    大多数苹果示例都使用第一种方法。为什么要分配、初始化和对象,然后立即释放?

    6 回复  |  直到 15 年前
        1
  •  71
  •   benzado    16 年前

    每个对象都有一个引用计数。当它变为0时,对象被解除分配。

    假设财产被声明为 @property (retain)

    您的第一个示例,逐行:

    1. 对象是由 alloc ,它的引用计数为1。
    2. self setAController: 方法,该方法向其发送 retain 消息(因为该方法不知道对象来自何处),将其引用计数增加到2。
    3. 调用代码不再需要对象本身,因此它调用 release ,将引用计数递减为1。

    规则是,如果你创建了一个对象,你有责任在处理完后释放它。在您的示例中,代码是在设置属性后使用TempaControl完成的。setter方法负责调用 如果它需要那个物体粘在周围。

    self.property = foo; [self setProperty:foo]; 而且 setProperty: 方法将根据需要保留或复制对象。

    如果财产已申报 @property (copy)

    如果财产已申报 @property (assign) 然后 没有声明对象的所有权,其他人需要保留它。在这种情况下,第一个示例是不正确的。这类属性很少见,通常仅用于对象委托。

        2
  •  31
  •   mmalc    16 年前

    至于为什么选择前者而不是后者:

    后者的正确表述是

    self.aController= [[[AController alloc] init] autorelease];
    

    与前者相比,这通过使用自动释放池增加了额外的开销,并且在某些情况下会导致对象的生命周期被不必要地延长(直到自动释放池被释放),这将增加应用程序的内存占用。

    aController = [[AController alloc] init];
    

    这就引出了示例代码中所示的实现:

    AController *tempAController = [[AController alloc] init];
    self.aController = tempAController;
    [tempAController release];
    

    这遵循最佳实践,因为:

    • 它避免了自动释放;
    • 它使内存管理语义立即变得清晰;
    • 它使用访问器方法来设置实例变量。
        3
  •  5
  •   Kendall Helmstetter Gelner    16 年前

    还请注意,您希望将代码缩减为一行,这也是许多人使用自动释放的原因:

    self.aController = [[[AController alloc] init] autorelease];
    

    虽然从理论上讲,iPhone autorelease更昂贵(从未听过明确的解释),因此您可能希望在将对象分配到其他位置后立即显式释放。

        4
  •  5
  •   leviathan    14 年前

    如果您使用的是Xcode,它可以帮助您使用静态分析器检测此类代码。 只需点击Build>&燃气轮机;构建和分析

    alt text

    alt text

        5
  •  4
  •   Ashley Clark    16 年前

    如果它被定义为 @property (readwrite, retain) id aController; @property (readwrite, assign) id aController; 然后,对release的额外调用将导致对象被释放。

        6
  •  2
  •   mk12    15 年前

    你也可以这样做

    @property (nonatomic, retain)AController *aController;
    ...
    self.aController= [[AController alloc] init];
    [aController release];