在他的书中,在非ARC环境中考虑第7章中的代码:
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对象,fyi,所以sum2
现在拥有一个对象(一个非自动释放的对象)(根据其他代码)这本书)
问题,评论2 - 我们发布了sum
- sum
只是作为一个空指针持续存在,直到它被“分配”给sum2
?由于sum2
拥有一个对象,因此在{1}}为评论1分配 new alloc'd对象时,sum2
仍然是之前对象的唯一所有者迭代,并不需要sum
。当[sum2 release]
出现在注释2之上时,该对象最终会消失,最终将被同一循环中的新对象替换。这是正确的解释吗?
最后,虽然我们永远不会释放[sum release]
,因为sum2
通过在最后执行`[sum release]',这会让程序没有内存泄漏,对吗?
答案 0 :(得分:0)
WRT评论1:
sum2 = [sum add:aFraction];
此调用意味着返回自动释放的对象。这是按惯例;只有以init
开头或被称为new
的方法才能返回非自动释放的对象,其他所有方法都应该自动释放。
WRT评论2:
在释放sum
后没有指向它的指针仍为非nil
,但它指向的是一个可能免费的对象。通过此引用访问对象将在某些时候引起问题;可能马上。指针不拥有任何东西;所有权的概念是在方法或阶级。例如
Foo *foo = [[Foo alloc] init];
Foo *foo2 = foo;
Foo *foo3 = foo2;
方法拥有 foo
,恰好有三个对同一个对象的引用。这没关系,只要你记住这个并且只有release
一次对象(你可以使用release
对象的任何引用。)