【问题标题】:Objective-C 2.0; Assigning a Property; Leaking Memory?目标-C 2.0;分配财产;泄漏内存?
【发布时间】:2009-05-03 22:21:17
【问题描述】:

我仍在学习 Objective-C 内存管理。我正在尝试在我正在构建的示例程序中实现几个简单的类。

例如,假设我有以下类定义:

 #import <UIKit/UIKit.h>

 @interface customViewController : UIViewController 
 {
    customObject *myCustomObject;
 }

 @property (retain) customObject *myCustomObject;

 - (void)replaceCustomObject:(customObject *)newObject;

 @end

对于属性,我使用标准的 synthesize 关键字...

@synthesize myCustomObject;

那么请假设在 customViewController 的实例中 myCustomObject 已经设置了一个有效值并且正在使用中。那么replaceCustomObject方法定义为:

 - (void)replaceCustomObject:(customObject *)newObject
 {
     //Does this cause a memory leak because I just assign over
     //the existing property? 
     self.myCustomObject = newObject;
 }

正如评论所问,这会泄漏内存吗? 或者这是用新对象替换先前对象的有效方法?

谢谢你,
弗兰克

【问题讨论】:

    标签: objective-c iphone memory-management


    【解决方案1】:

    正如其他人所提到的,您的代码完全有效,并且在分配给属性时不会泄漏内存。

    如果您忘记实现正确的dealloc 方法,当您的customViewController 被销毁时,分配的最后一个对象将被泄露。正确的 dealloc 实现如下所示:

    - (void)dealloc
    {
        self.myCustomObject = nil;
        [super dealloc];
    }
    

    【讨论】:

    • 您能进一步解释一下吗?我从未见过将属性设置为零。这等于做 [self.myCustomObject release] 吗?这就是我学会在 dealloc 方法中处理这个问题的方式......
    • 发送 [self.myCustomObject release] 是危险的,因为这样做之后,self.myCustomObject 仍然指向现在发布的对象!在 dealloc 方法中,它可能是安全的,因为 self 无论如何都会被销毁,但我不喜欢有特殊的规则要记住。为了安全起见,您还可以执行以下操作:[myCustomObject release]; myCustomObject = nil;
    【解决方案2】:

    这是完全有效的,并且不会泄漏内存。合成访问器正确管理保留计数。

    (顺便说一句,你不需要那个 replaceCustomObject: 方法;因为你的属性默认是读写的,你有一个自动生成的 setCustomObject: 方法,你的类的客户端可以使用,它遵循正常的 Cocoa 命名约定。)

    【讨论】:

    • 我知道我不需要 replaceCustomObject: 方法。这只是我说明我的总体目标的一种方式。你可以想象,我使用它的地方不仅仅是分配一个属性。 :-) 感谢您回答我的问题。
    【解决方案3】:

    根据this,如果你在声明中使用(retain),合成方法会先释放旧值,然后保留新值:

    if (property != newValue) {
        [property release];
        property = [newValue retain];
    }
    

    【讨论】:

      【解决方案4】:

      属性访问器语法

      self.x = y;
      

      和显式调用setter方法效果一样:

      [self setX:y];
      

      访问器方法将执行它所编写的任何操作。在您的情况下,对于已被 @synthesized 的 @property(retain) 属性,访问器将释放旧对象并保留新对象。

      因此,无论是显式调用还是通过 '.' 调用 setter语法,会做正确的事——包括正确的内存管理。

      简而言之:不,这不会泄漏内存。

      【讨论】:

        猜你喜欢
        • 2012-12-06
        • 1970-01-01
        • 2010-12-21
        • 2016-09-12
        • 2023-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-17
        相关资源
        最近更新 更多