【问题标题】:Starting Objective-C, memory leak concerns启动 Objective-C,内存泄漏问题
【发布时间】:2010-06-04 05:23:23
【问题描述】:

大家好,我开始使用 Objective-C,我想确保我得到正确的内存/属性。

假设如下代码:

@interface Rectangle : NSObject 
{
    Vector2* origin;
    //[...]
}

Rectangle* myRect  = [[Rectangle alloc] init];
myRect.origin.x = 100.0f;
[myRect print];
myRect.origin = [[Vector2 alloc] init]; //hummm.. 2 concerns here.

关注点 1:

假设 origin 是标准(分配)综合属性:

在分配新的 Vector2 时,myRect 之前的原始引用计数是否会自动变为 0,而 GC 稍后会处理它?还是我必须在属性内显式调用 release?

关注点 2:

假设 origin 将是一个“保留”属性:(顺便说一句:在声明合成保留属性时会自动生成那种代码,这可能吗?)

-(void) setOrigin: (Vector2*)newOrigin {
   [newOrigin retain];
   [origin release]
   origin = newOrigin;
}

那么当做:

myRect.origin = [[Vector2 alloc] init]

这不会导致双重引用计数增加,然后需要调用两次释放以避免泄漏?在使用库/其他人的代码来避免此类问题时,你们是否依赖有据可查的代码(知道这是一个保留属性),还是有一些更安全的分配/初始化对象的方法?

感谢您的提示!

【问题讨论】:

  • 澄清一下 - origin 应该是 Vector2* 类型,对吧?
  • 关于合成属性生成什么样的代码,您发布的是一个选项,是我在属性和垃圾收集之前使用的选项。还有其他变化。此外,在原子属性中,这些语句将被某种互斥体括起来。

标签: objective-c memory


【解决方案1】:

关注点 1:
[...] myRect 之前的原始引用计数是否自动变为 0

不,assign 属性正如它所说的那样 - 分配。它不保留也不释放 - 在这种情况下您必须手动处理。

关注点 2:

myRect.origin = [[Vector2 alloc] init]

这不会导致双引用计数增加

是的,这就是你要使用自动释放的原因:

myRect.origin = [[[Vector2 alloc] init] autorelease];

...或手动释放它:

Vector2 *v = [[Vector2 alloc] init];
myRect.origin = v;
[v release];

至于如何处理这些问题:

  • 阅读memory management guide
  • 查看文档或属性声明的内容
  • 对于传递给方法的参数,始终假定被调用者在需要时保留 - 除非另有说明

【讨论】:

  • 这个答案假定origin 是对象类型。如果不是,那么由于微妙和不幸的原因,这个问题和这个答案根本没有任何意义。如果是,那么快乐的一天...... Georg 打败了我。
  • 对。由于您分配或保留了vector2,因此您必须释放它。像这样给 myRect 将导致 myRect 也保留它。 (然后 myRect 将反过来负责在完成后释放它。)
  • 好的,因此大多数接收 NSObject*(或派生的)作为参数的设置器将主要是保留属性,因为分配会有点......风险。 @property (retain) someVar 和 @synthesize 之后怎么样。这会自动生成保留/释放旧/分配代码还是您必须实现每个保留属性?谢谢!
  • @turbo:在某些重要情况下,保留属性没有意义 - 请参阅 weak referencesCore Foundation
  • 至于@synthesize,它将为您生成保留/释放设置器,请参见例如here.
猜你喜欢
  • 1970-01-01
  • 2011-07-29
  • 1970-01-01
  • 1970-01-01
  • 2013-02-04
  • 1970-01-01
  • 2011-06-07
  • 1970-01-01
相关资源
最近更新 更多