2011-08-10 66 views
1

對於OC,C,C++,C#等多種年齡段的新手來說,現在思維有點令人難以置信。目標C:關於分配,保留和釋放的新手問題

考慮:

// AnInterface.h 
@interface AnInterface : NSObject 
{ 
} 

@property (retain) SomeObject* m_Object; 

// AnInterface.m 
#import "AnInterface.h" 

@synthesize m_Object; 

-init 
{ 
    self= [super init]; 
    if(!self) 
    return (nil); 

    SomeObject* pObject= [[SomeObject alloc] init]; 
    self.m_Object= pObject; 
    [pObject release]; 
} 

我敢肯定上面是正確的。然而, 爲什麼不只是做:

self.m_Object= [[SomeObject alloc] init]; 

請問這項工作呢?它違反了一些內存管理原則嗎?它似乎應該工作,一行而不是三,但我肯定我一定是失去了一些東西....

任何洞察力將不勝感激。

+0

非常接近重複:http://stackoverflow.com/questions/3722998/objective-c-memory-management-question,http://stackoverflow.com/questions/4210700/objective-c-memory -management-question –

+0

不要調用ivars或屬性'm_'任何東西; Objective-C中沒有使用所有那種愚蠢的gobbledegook符號。 – bbum

+0

@Josh - 所以,根據那篇文章,如果我剛剛直接分配了實例(m_Object = ...),而不是使用setter,它會工作得很好,對不對? – GTAE86

回答

2

原因是因爲你定義了屬性m_Object來保留,所以它會導致內存泄漏,因爲alloc/init調用導致保留+1,那麼屬性將保留給它至少一個保留計數+2。如果您想使其成爲一條隨意濫用自動發佈池的行。

self.m_Object= [[[SomeObject alloc] init] autorelease]; 
+0

我想知道是否是這樣的 - 謝謝。 – GTAE86

+1

如果你想知道爲什麼我說「濫用自動發佈池」,請參閱http://stackoverflow.com/questions/613583/why-is-autorelease-especially-dangerous-expensive-for-iphone-applications – Joe

+0

是的,我在教程中閱讀這個想法。來自C和C++,我理解和實踐良好的內存管理。然而,OC似乎向後彎曲使其變得困難,而其他語言似乎使得它多年來不那麼繁重。 – GTAE86

1

泄漏物體。由於alloc返回擁有參考號,並且retain第二次要求所有權,因此您需要撥打release來平衡alloc,否則對象將認爲您想永遠保留它並永不釋放。

1
self.m_Object = [[SomeObject alloc] init]; 

這會導致過度保留。你得到一個claim of ownershipalloc,另一個通過setter,它被聲明爲retain這個新值。由於您只有一個指向新值的指針,因此您有太多索賠。當設置器再次使用:

self.m_Object = anotherObject; 

原來的對象將收到只有一個release消息,你將失去的指針。既然你對這個對象有兩個聲明,它不會被釋放,你就會泄漏。

屬性訪問:self.m_Object = obj;被編譯器翻譯爲[self setM_Object:obj];。也就是說,調用由@synthesize指令創建的屬性的setter方法。這個設置方法保留了它的論點。另一種選擇是直接在您的init方法使用伊娃:

-init { 
    //... 
    m_Object = [[SomeObject alloc] init]; 
    //... 
} 

那麼你只有一個要求此對象上,由於使用的alloc。既然你也有一個對象的引用,這是正確的。