2009-06-21 72 views
2

在我的項目中,我正在使用propertyList來維護數據。 plist文件被命名爲「DataBase.plist」。 DataBase.plist的根目錄是一個字典,其中包含5個字典作爲子項目...現在,子字典包含4個字符串,其中一個始終是具有密鑰「URL」(不帶引號)的Web地址.... i 「M運行下面的代碼以提取該URL關鍵字的值,但它不工作了..從屬性列表中讀取NSDictionary Keys

NSString *path = [[NSBundle mainBundle] pathForResource:@"DataBase" ofType:@"plist"]; 
NSDictionary *rootDict = [[NSDictionary alloc] initWithContentsOfFile:path]; 
NSString *URLforAll = [[NSString alloc] init]; 
for (id key in rootDict) 
{ 
    if(key == rowString) 
    { 
     NSDictionary *dict = [rootDict objectForKey:key]; 
     URLforAll = [dict objectForKey:@"URL"]; 
    } 
} 

的rowstring是(我的字符串,其值是一樣的,在選定單元格的文本測試它,它是準確的)。 請幫助我,如果你可以....我會很感激

+0

這個問題可以更清楚地命名,也許「從屬性列表文件中讀取NSDictionary鍵」。它確實沒有看到與鍵值編碼有關的任何事情(查看它),當然沒有特定的iPhone。相應地重新標記。 – 2009-06-21 05:07:20

回答

3

嘗試使用[key isEqualToString: rowString]而不是直接使用==比較key和rowString。我認爲==比較了對象的指針值,即使字符串匹配,這些值也不相等。

另外 - 就像旁白一樣,在設置之前,您不需要初始化URLforAll。當您將其設置爲[dict objectForKey:@"URL"]時,您將失去指向您已創建的對象的指針,並且它將被泄漏。相反,只要說NSString *URLforAll = nil;或創建一個新的字符串和autorelease它,這樣的對象會被自動清理:

NSString * URLforAll = [[[NSString alloc] init] autorelease]; 
+1

所有不錯的建議。 ==你比較內存地址(指針)是正確的。與C++不同,Objective-C不支持重載操作符。事實上,即使是Java開發人員也面臨同樣的錯誤。我可能會避免首先創建一個自動釋放對象 - 如果URL forAll(命名較差)在for循環之後爲零,則創建一個對象。如果它是從一個方法返回的,它應該只能被自動釋放。 – 2009-06-21 05:05:00

+0

第一次 - 謝謝你幫助-isequalToString完美地工作.... ..。 ....和上面的代碼後,我添加[URLforAll發佈];而不是使用[[[[NSSTring alloc] init] autorelease];內存是否仍然泄漏...如果它確實請告訴我怎麼... 請告訴我...並且我讀了一些使用autorelease for iphone的建議.... 和關於名稱的URLofAll它被更改爲這個問題......感謝百萬人的幫助 – valiantb 2009-06-21 16:16:50

+1

你根本不需要分配/ init URLforALl。只需將它初始化爲零即可。字典的objectForKey:方法將返回給你一個自動釋放對象。 – amrox 2009-06-21 16:20:49

2

您還沒有通過字典需要循環。只要問一下你想要的數據。

NSString *path = [[NSBundle mainBundle] pathForResource:@"DataBase" ofType:@"plist"]; 
NSDictionary *rootDict = [[[NSDictionary alloc] initWithContentsOfFile:path] autorelease]; 
NNSString *URLString = [[rootDict objectForKey:key] objectForKey:@"URL"]; 

// do something or return URLString... 
3

此外,在您的代碼:

NSString *URLforAll = [[NSString alloc] init]; 

這從不感覺。以下是一些問題:

  • 您分配了一個對象,然後用URLforAll = [dict objectForKey:@"URL"];不加區分地重寫。所以你需要在覆蓋之前釋放它。
  • 它被分配(即,在循環結束時,你「自己」,並必須將其釋放。但 [dict objectForKey:@"URL"]返回一個對象,你並不擁有。因此,在循環結束時,你不知道你是否擁有URLforAll與否。
  • 最後,[[NSString alloc] init]永遠是有道理的,因爲你應該只使用@"",它返回一個恆定的,空的,NSString這是不受retain/release/autorelease問題。

處理也與isEqualToString的問題,但忽略了AMROX更好的解決方案,代碼將是:

NSString *path = [[NSBundle mainBundle] pathForResource:@"DataBase" ofType:@"plist"]; 
NSDictionary *rootDict = [[NSDictionary alloc] initWithContentsOfFile:path]; 
NSString *URLforAll = @""; 
for (id key in rootDict) { 
     if ([key isEqualToString:rowString]) { 
       NSDictionary *dict = [rootDict objectForKey:key]; 
       URLforAll = [dict objectForKey:@"URL"]; 
     } 
} 
[[URLforAll retain] autorelease]; 
[rootDict release]; 

注意objectForKey可能返回一個內部參考的對象,當你釋放字典,因此需要保留的對象,如果你想保持它周圍長於字典的生活將變得無效。

amrox的使用:

NSString *path = [[NSBundle mainBundle] pathForResource:@"DataBase" ofType:@"plist"]; 
NSDictionary *rootDict = [[NSDictionary alloc] initWithContentsOfFile:path]; 
NSString *URLString = [[rootDict objectForKey:key] objectForKey:@"URL"]; 
[[URLString retain] autorelease]; 
[rootDict release]; 
if (!URLString) { 
    URLString = @""; 
} 

是一個更好的解決方案,但你應該undertand有什麼問題你原來的解決方案,以及。