2011-02-12 37 views
4

我學習內存管理,但我真的不明白,爲什麼我要實現我的getter屬性,像這樣:保留並自動釋放在getter方法

-(Weapon*)myWeapon 
{ 
    [myWeapon retain]; 
    [myWeapon autorelease]; 
    return myWeapon; 
} 

我明白我寫的,但我可以」想象爲什麼它很重要?你能解釋爲什麼我應該這樣做嗎?

回答

10

這是從內存管理編程指南:

技術1 在技術1,值getter返回在呼叫範圍內自動釋放:

- (NSString*) title { 
    return [[title retain] autorelease]; 
} 

- (void) setTitle: (NSString*) newTitle { 
    if (title != newTitle) { 
     [title release]; 
     title = [newTitle retain]; // Or copy, depending on your needs. 
    } 
} 

因爲從get訪問器在當前作用域中自動釋放,如果屬性值發生更改,則它仍然有效。這使訪問器更加健壯,但是以額外開銷爲代價。如果您期望經常調用getter方法,則保留和自動釋放對象的額外成本可能不值得性能成本。

技術2 像技術1,技術2也使用一個自動釋放技術,但這次是在setter方法這樣做:

- (NSString*) title { 
    return title; 
} 

- (void) setTitle: (NSString*) newTitle { 
    [title autorelease]; 
    title = [newTitle retain]; // Or copy, depending on your needs. 
} 

技術2的性能比的情況下技術1顯著更好吸氣劑比吸氣劑更經常地被調用。

技術3 技術3避免了使用自動釋放的共:

​​

由技術3中使用的方法是良好的頻繁調用的獲取和設置方法。對於不希望延長其值的生命週期的對象(如集合類)也是有益的。它的缺點是可能會立即釋放舊值(如果沒有其他所有者),如果另一個對象保持非擁有引用,則會導致問題。例如:

NSString *oldTitle = [anObject title]; 
[anObject setTitle:@"New Title"]; 
NSLog(@"Old title was: %@", oldTitle); 

如果anObject是擁有原始標題字符串的唯一對象,則該字符串將在設置新標題後解除分配。由於oldTitle是一個已釋放的對象,日誌語句會導致崩潰。

編輯:基本上保留然後自動釋放的重點是確保如果在調用範圍有機會保留它之前更改屬性值,則該對象將不會被釋放。除非你有異步代碼,否則這通常不是問題。在大多數情況下,- (Weapon *)myWeapon { return myWeapon; }就好了(再加上速度更快)。

+0

優秀的答案,我從中學到了一些有用的東西。 – Dave 2011-02-13 00:14:15