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函数正在返回一个分配的对象,fyi,所以sum2现在拥有一个对象(一个非自动释放的对象)(根据书中的其他代码)

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

最后,虽然我们从来没有 release sum2,因为sum=sum2通过在最后做一个 `[sum release]',这使得程序没有内存泄漏,对吗?

4

1 回答 1

0

WRT评论1:

sum2 = [sum add:aFraction];

这个调用意味着返回一个自动释放的对象。这是约定俗成的;只有以init或被调用的方法new应该返回一个非自动释放的对象,所有其他的都应该是自动释放的。

WRT评论2:

没有 aftersum被释放,指向它的指针仍然是 non- nil,但是它指向的是一个可能被释放的对象。通过此引用访问对象有时会导致问题;可能马上。指针不拥有任何东西;所有权的概念是在方法或类级别。例如

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

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

于 2012-11-14T10:15:30.047 回答