2011-04-13 59 views
0

我有一個很大的NSDictionary,裏面有一個較小的NSDictionary。我想autorelease更大的一個,並保留第二。我有這樣的代碼在我的init方法:Objective-C:在自動發佈的NSDictionary中保留一個NSDictionary

// Autoreleased stage dictionary 
NSString *plistPath = [[NSBundle mainBundle] pathForResource:map ofType:@"plist"]; 
NSDictionary *mapDict = [NSDictionary dictionaryWithContentsOfFile:plistPath]; 

// Owned items 
citiesDictionary = [[mapDict objectForKey:@"Cities"] retain]; 

citiesDictionary在類接口聲明爲:

NSDictionary *citiesDictionary; 

如果我嘗試使用釋放citiesDictionary中的dealloc下面一行它崩潰。

[citiesDictionary release]; 

但是,如果我沒有的dealloc citiesDictionary,我得到儀器報道時,我的dealloc包含citiesDictionary類內存泄漏。我承認mapDict在初始化結束時被釋放。這個取消分配是否會影響citiesDictionary,即使我稱之爲保留?

如果是這樣,我怎樣才能保留較小的字典,同時釋放較大的字典呢?分配citiesDictionary時,我嘗試了不同的事情,但似乎沒有任何工作正確。一些方法我試過:

citiesDictionary = [[mapDict objectForKey:@"Cities"] copy]; 

citiesDictionary = [NSDictionary initWithDictionary:[mapDict objectForKey:@"Cities"]]; 

甚至

citiesDictionary = [NSDictionary initWithDictionary:[[mapDict objectForKey:@"Cities"] copy]]; 

任何幫助表示讚賞。謝謝。

回答

0

感謝您的意見球員。經過幾個小時我的頭撞到問題,我發現是什麼造成的。

這完全是我的錯:我在一個與citiesDictionary相關的NSMutableDictionary中插入了一個內存管理有缺陷的自定義類,並釋放了另一件事導致內存損壞。

現在,無論

citiesDictionary = [[mapDict objectForKey:@"Cities"] release]; 

citiesDictionary = [[mapDict objectForKey:@"Cities"] copy]; 

完全正常工作。

PS .: StackOverflow overlords:鑑於問題的解決方案與主要問題完全無關,我應該去投票刪除這個問題還是保留以供參考?

+0

我會接受你自己的答案和投票的答案,幫助你弄清楚。 – 2011-04-14 00:33:13

+0

已經投了票,謝謝。 – 2011-04-14 12:54:59

1

將字典複製到citiesDictionary

NSString *plistPath = [[NSBundle mainBundle] pathForResource:map ofType:@"plist"]; 
NSDictionary *mapDict = [NSDictionary dictionaryWithContentsOfFile:plistPath]; 
citiesDictionary = [[mapDict objectForKey:@"Cities"] copy]; 

現在即使可以隨時釋放包含的對象,您仍然可以確保擁有字典的副本。記住隨後還要發佈citiesDictionary。

使用copy時請注意,即使原始對象是NSMutableDictionary,您也將始終得到不可變的NSDictionary。如果需要,使用mutableCopy獲得NSMutableDictionary

+0

謝謝你的回答。我用一些我試過的東西稍微擴展了這個問題。我已經嘗試複製字典,但它仍然在[citiesDictionary發行]上崩潰。 – 2011-04-13 00:55:05

+1

您確定除了'-dealloc'之外,您還沒有在代碼的其他地方發佈'citiesDictionary'? – 2011-04-13 00:57:17

+0

是的,我很確定我沒有明確地在其他地方釋放它。 – 2011-04-13 01:02:24

1

您在某處過度發佈citiesdictionary,因爲您已經在init方法中調用retain。 Map dict只在釋放你的citiesdictionary時纔會釋放一次,但不會取消你在init方法中完成的保留。

您應該嘗試檢查您的其他方法是否將釋放聲明添加到字典中,或者讓靜態分析器告訴您。

+0

感謝您的評論。看到我的答案是什麼導致它(完全是我的錯)。如何使用靜態分析器?我通常在樂器上使用「泄漏」設置。 – 2011-04-13 20:06:51