2012-11-14 31 views
0

在他的书中,考虑从第7章的代码,在非ARC环境:内存分配例如由斯蒂芬·科昌

Fraction *aFraction = [[Fraction alloc] init]; 
Fraction *sum=[[Fraction alloc] init],*sum2; 
int i, n=5, pow2=2; 

[sum setTo: 0 over: 1]; 

for (i = 1; i <= n; ++i){ 
[aFraction setTo: 1 over: pow2]; 
sum2 = [sum add:aFraction]; // Comment 1 
[sum release]; 
sum = sum2; // Comment 2 
pow2 *=2; 
} 

[sum doSomething]; 
[sum release]; 

有人可以证实我的理解是正确的:

注,评论1 - 我知道这add函数返回一个alloc'd对象,仅供参考,所以sum2现在拥有(在这本书按照其他代码)的对象(非自动释放对象)

问题,评论2 - 我们发布sum -也是如此只是作为空指针持续存在,直到它被“分配”为sum2?由于sum2拥有一个对象,因此sum2在注释1中分配了新的分配对象时,sum仍然是先前迭代中对象的唯一所有者,并且[sum2 release]不是必需的。当在评论2上方出现[sum release]时,该对象最终消失,最终在同一循环中被新的替换。这是正确的解释吗?

最后,虽然我们从来没有发布sum2,因为sum=sum2在最后做了一个`[sum release]',这就让程序没有内存泄漏,对吗?

回答

0

WRT评论1:

sum2 = [sum add:aFraction]; 

这意味着调用一个autorelease'd对象的回报。这是惯例;只有以init开头或称为new的方法才会返回一个非自动释放对象,其他所有对象都应该是自动释放的。

WRT评论2:sum被释放的指针没有经过

它仍非nil,但是它所指向的是一个潜在的free'd对象。通过此引用访问对象将在某个时刻引发问题;可能立即。指针没有自己的什么;所有权的概念处于方法级或级别级。例如

Foo *foo = [[Foo alloc] init]; 
Foo *foo2 = foo; 
Foo *foo3 = foo2; 

的方法拥有foo,并且恰好有三个引用同一个对象。这没关系,只要你记住这个并且只有release这个对象一次(你可以使用任何对release的引用)。