2012-11-14 21 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的引用)。