目标C:关于分配,保留和释放的新手问题

时间:2011-08-10 20:05:21

标签: objective-c memory-management

OC的新手,多年的C,C ++,C#,心灵现在有点令人难以置信。

假设:

// AnInterface.h
@interface AnInterface : NSObject  
{  
}  

@property (retain) SomeObject* m_Object;  

// AnInterface.m
#import "AnInterface.h"  

@synthesize m_Object;  

-init
{  
  self= [super init];  
  if(!self)  
    return (nil);  

  SomeObject* pObject= [[SomeObject alloc] init];  
  self.m_Object= pObject;  
  [pObject release];
}  

我很确定以上是正确的。然而, 为什么不这样做:

self.m_Object= [[SomeObject alloc] init];  

这也有用吗?它违反了一些内存管理原则吗?它似乎应该工作,一行而不是三行,但我确信我一定会错过一些东西......

任何见解都将受到赞赏。

3 个答案:

答案 0 :(得分:2)

原因是因为您将属性m_Object定义为保留所以它会导致内存泄漏,因为alloc / init调用导致保留+1,然后属性将保留至少保留计数为+2。如果您想让它在一行中随意滥用自动释放池。

self.m_Object= [[[SomeObject alloc] init] autorelease]; 

答案 1 :(得分:1)

泄漏物体。由于alloc会返回一个拥有的引用,并且retain第二次声明所有权,您需要调用release来平衡alloc或者您认为要保留的对象它永远永远不会被解除分配。

答案 2 :(得分:1)

self.m_Object = [[SomeObject alloc] init];

这导致过度保留。您为alloc获得一个claim of ownership,通过setter获得另一个{{3}},其被声明为retain新值。由于您只有一个指向新值的指针,因此您有太多的声明。再次使用setter时:

self.m_Object = anotherObject; 

原始对象只会收到一条release消息,您将丢失指针。由于您对该对象有两个声明,它将不会被释放,并且您将有泄漏。

属性访问:self.m_Object = obj;由编译器翻译为[self setM_Object:obj];。也就是说,调用由@synthesize指令创建的属性的setter方法。该setter方法保留了它的参数。另一种选择是直接在init方法中使用ivar:

-init {
    //...
    m_Object = [[SomeObject alloc] init];
    //...
}

然后,由于alloc的使用,您对此对象只有一个声明。由于您还有一个对象的引用,这是正确的。