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];
这也有用吗?它违反了一些内存管理原则吗?它似乎应该工作,一行而不是三行,但我确信我一定会错过一些东西......
任何见解都将受到赞赏。
答案 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
的使用,您对此对象只有一个声明。由于您还有一个对象的引用,这是正确的。