2009-05-29 114 views
1

我試圖填充字典動態在for循環中,像這樣:目標C填充對象

僞代碼

myObject = new Object 
myDict = new Dictionary 
for(int i; i < 10;i++) 
    myObject.value1 = new data from somewhere 
    myObject.value2 = new data from somewhere 
    myDic = value:myObject key:i 
end for 

所以我的問題是在Objective-C,我能繼續分配新的數據到myObject而不是每次在循環中釋放它?我仍然試圖找出objective-c中的內存管理。

+0

你會在循環中釋放什麼?所有數據(鍵,值和字典本身)仍處於活動狀態。 – 2009-05-29 03:26:34

回答

5

這取決於myObject究竟是什麼以及如何定義其屬性。假設你讓他們定義釋放如這裏:

@property (nonatomic, retain) SomeClass *myProperty; 

然後是的,你可以做到這一點。通過objective-c發佈,setters會自動爲您合成,並在保留和分配新值之前設置爲零的舊屬性值。

但是,儘管你的內存管理沒有問題,但是你的代碼仍然存在問題。請記住,myObject是一個指針,就像在C或C++中一樣。這意味着如果將它添加到myDic,然後稍後修改對象的屬性(例如在for循環的下一次迭代中),那麼當您將對象從字典中的某個點拉出時,這些更改將會反映出來未來。你需要的是這樣的:

myObject = nil 
myDict = new Dictionary 
for(int i; i < 10;i++) 
    myObject = new Object 
    myObject.value1 = new data from somewhere 
    myObject.value2 = new data from somewhere 
    myDic setValue:myObject forKey:i 
    myObject release 
end for 

這樣做是釋放myObject把它在字典中後(所有可可集合類保留,你把他們的任何對象,並釋放對象時,他們要麼刪除或集合本身被解除分配),所以你沒有泄漏,並且在每次迭代時都分配一個新的實例Object,所以你不會一遍又一遍地修改同一個對象。

如果您還沒有閱讀過Apple的Memory Management Guide for Cocoa,我強烈建議您這樣做。這是非常豐富的。

0

Objective-C中的內存管理是通過引用計數完成的。當您分配一個對象時,它的引用計數爲1.'retain'方法增加引用計數,'release'則減少引用計數。當引用計數達到0時,將調用'dealloc'方法(您不應該明確地調用'dealloc')並釋放該對象。

您也可以在對象上調用'autorelease',這會在一段時間後減少引用計數。這使您可以使用該對象而不必擔心釋放它。

對於你的問題。將某個對象添加到容器時,將在插入的對象上執行「保留」調用。這意味着,你必須「釋放」插入對象:

NSMutableDictionary *myDict = [[NSMutableDictionary alloc] init]; 
for(int i = 0; i < 10; ++i) { 
    Object *myObject = [[Object alloc] init]; 
    [myDict setObject:myObject forKey:[NSNumber numberWithInt:i]]; 
    [myObject release]; 
} 

您還可以使用:

Object *myObject = [[[Object alloc] init] autorelease]; 

,你就不必叫「發行」插入後。

0

你的問題是非常開放的,這取決於你的ObjectDictionary是如何實現的。

首先,你只分配一次對象,並在循環中釋放它10次 - >內存問題。

如果我們過去了。假設你在循環的每次迭代中分配新的對象。

以擴展NSObject的NSMutableDictionary和MyObject作爲對象和詞典的示例。

當您在NSMutableDictionary實例上調用setObject:forKey時,該對象將接收保留調用,以便字典保持對它的引用。

release它在迭代結束時,字典仍然保持對它的引用,所以它沒問題。

另一件事要記住,如果你使用這一個大循環:

Object *myObject = [[[Object alloc] init] autorelease]; 

是自動釋放的對象去自動釋放池的事實。在當前事件處理結束時池被清理乾淨。如果創建大量對象,則在事件處理結束時可能需要很長時間才能完成。在這種情況下,您可能選擇僅爲循環創建自己的自動釋放池 - 但我想這是更高級的主題。

肯定看看Apple的一些Objective-c和內存管理參考。

0

你正在做的事情只有一個對象,並將該對象放入字典十次。它不會將十個單獨的對象放入字典中。