间接分配和初始化声明的@property的好处

时间:2010-09-14 23:03:41

标签: objective-c

当涉及分配和初始化被声明为类的@properties的对象时,我在样本代码的各个位中看到了两个主要模式,因此给出了以下(组成)标题代码 -

@interface Class : Superclass {  
    Object *anObject;  
}  
@property (nonatomic, retain) Object *anObject;  

第一个直接任务:

self.anObject = [[Object alloc] init];

第二种间接方法创建一个临时对象,然后将其分配给属性并释放:

Object *tempObject = [[Object alloc] init];
self.anObject = tempObject;
[tempObject release];

第二种方法比第一种方法有什么好处?

3 个答案:

答案 0 :(得分:3)

这两个代码块之间的区别在于第一个是内存泄漏。当您致电[Object alloc]时,您将获得该对象的“所有权”,并有时负责-release。然后,当您调用[self -setAnObject]时,它需要第二个所有权,将新实例的保留计数设置为2.如果执行创建的方法返回而不放弃其对新实例的所有权,则结束了泄漏。

试试这个:

self.anObject = [[[Object alloc] init] autorelease];

这是有效的,因为[NSObject -autorelease]返回self并且还会在将来的某个时间调度-release调用,这通常意味着在当前运行循环结束时。

答案 1 :(得分:2)

正如之前的海报正确指出的那样,第一种方法(至少是它当前编码的方式)是内存泄漏。然而,第二种方法在技术上更有效,因为与自动释放池相关的开销有点小。

向池中添加一个额外的对象可能不会产生可测量的差异,但是不必要地向池中添加大量对象,因此通常第二种方法是首选。

答案 2 :(得分:2)

你可能已经错过了第一个模式。直接赋值(对实例变量)应为:

anObject = [[Object alloc] init];

绕过setter,从而保留适当的保留计数为1。

糟糕的是它避免了setter(从而导致潜在的代码重用/增强问题)。

好处是它避免了设置器(如果它在配置文件中显示为热点,则很重要)。