2012-05-04 50 views
0

这是一个与Objective-C内存管理有关的问题。Objective-C .mm in initializer and class factory method

About Memory Management页有一些例子

- (NSString *)fullName { 
    NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@", 
            self.firstName, self.lastName] autorelease]; 
    return string; 
} 

,第二个

- (NSString *)fullName { 
    NSString *string = [NSString stringWithFormat:@"%@ %@", 
            self.firstName, self.lastName]; 
    return string; 
} 

唯一的区别是,在第一实施例的初始化被调用,并且在所述第二类工厂方法。

基本内存管理规则部分是说,在一个alloc调用后,我将拥有我分配的对象。所以在第一个例子中,我分配一个对象并同时初始化它。在这个我自己的对象,并有它release它。在第二个例子中,我没有。但是工厂方法stringWithFormat:在一次调用中做了同样的事情,我的意思是分配对象并初始化它?

所以主要问题是,为什么我不必在第二个示例中释放对象? 在实现类工厂方法时是否有任何特殊的内存管理规则?

+0

p.s.所有这些基本上都是随着ARC的引入而开展的。你可能会更好地阅读。在ARC下,你简单地忽略诸如retain,release,autorelease之类的东西(试图调用这些方法会导致编译错误),并且知道一切都会正常工作。 – ericg

+0

答案基本上是正确的,只是他们声明从类工厂方法返回的对象是autoreleased。重要的是你不拥有它,没有权利或责任来释放它。它可能会或可能不会被自动释放。可能会有完全不同的内存管理方案。它可能会返回一个单身人士。它可能会返回一个永久性的共享值对象(比如'NSNumber'为0值数字对象的所有请求保留一个公共实例)。等等 –

回答

2

按照惯例,类工厂方法将返回autorelease池中的对象。它已经为你完成了alloc,init,autorelease,就像在第一个例子中一样。除非你保留它,否则当池被排空时,它将被释放。

+0

那么按照惯例,一个类工厂方法在执行时还必须执行autorelease吗? –

+0

是的,它应该。 – ericg

0

你是对的,工厂方法在内部调用alloc,并因此返回保留对象,但它将该对象添加到最近的autorelease pool,因此当该池将被排空时,该对象将被释放。

1

在第二个示例中,您没有创建该字符串。您只能通过调用以allocnewcopymutableCopy开头的方法来创建对象。

如果您愿意,您可以通过调用retain获得所有权,但您也可以负责调用release。在这个例子中,没有必要。你不再需要这个字符串。来电者用它做的是他们的责任。

当调用这样的工厂方法时,通常会收到一个自动释放对象。但你并不需要考虑这一点。因为没有创建它(因为你没有使用与allocnewcopy,或mutableCopy开头的方法来获取字符串),所有你需要做的是想保留计数三角洲 - 你需要保留它,以防止它从你下面消失。由于它只是返回给调用者,所以在这个例子中的答案是否定的。