1

我使用一個plist文件以獲得其顯示在tableview中問題與NSMutableArray的和valueforkey

plist中看起來像這個網站的列表:

<array> 
     <dict> 
      <key>site</key> 
      <string>http://yahoo.com</string> 
      <key>title</key> 
      <string>Yahoo</string> 
     </dict> 
     <dict> 
      <key>site</key> 
      <string>http://google.com</string> 
      <key>title</key> 
      <string>Google</string> 
     </dict> 
//...etc 
    </array> 
    </plist> 

我沒有問題顯示此:

NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"TestData" ofType:@"plist"]]; 
     [self setContentsList:array]; 

* 問題是當我嘗試搜索內容時,我想從搜索結果中獲取valueforkey @「site」以使用它在didSelectRowAtIndexPath方法:*

NSMutableArray *contentsList; 
    NSMutableArray *searchResults; 
    NSString *savedSearchTerm; 
--------------------- 
- (void)handleSearchForTerm:(NSString *)searchTerm 
{ 


    [self setSavedSearchTerm:searchTerm]; 

    if ([self searchResults] == nil) 
    { 
     NSMutableArray *array = [[NSMutableArray alloc] init]; 
     [self setSearchResults:array]; 
     [array release], array = nil; 
    } 

    [[self searchResults] removeAllObjects]; 

    if ([[self savedSearchTerm] length] != 0) 
    { 
     for (NSString *currentString in [[self contentsList] valueForKey:@"title"]) 
     { 
      if ([currentString rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound) 
      { 
       [[self searchResults] addObject:currentString]; 
       // NSDictionary *dic= [[NSDictionary alloc]allKeysForObject:searchResults]; 
      } 
     } 
    } 

} 

的didSelectRowAtIndexPath方法用於在網頁視圖中打開該網站

- (void)tableView:(UITableView *)tableView 
didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 


    NSString *arraySite = [[[self searchResults] objectAtIndex:indexPath.row] valueForKey:@"site"]; 

    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:arraySite]]]; 
    [self performSelector:@selector(showSearch:) withObject:nil afterDelay:0]; 

} 

錯誤,我得到:

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSCFString 0x6042730> valueForUndefinedKey:]: this class is not key value coding-compliant for the key site.' 

回答

7

基礎知識

當你從那個plist中讀出數組,陣列看起來如下:

(
    { 
     "site" = "http://yahoo.com", 
     "title" = "Yahoo" 
    }, 

    { 
     "site" = "http://google.com", 
     "title" = "Google" 
    }, 

    … 
) 

它是一個數組,其元素是字典,含有兩個鍵和它們的對應的值中的每個字典。

當您使用KVC方法-valueForKey:傳遞鍵title在陣列上,它返回另一個數組,其元素是對應於該密鑰的值:

(
    "Yahoo", 
    "Google", 
    … 
) 

所得陣列不持有與參照原始數組。

的問題

-handleSearchForTerm:,你只包含從原始數組標題的數組。對於每一個標題,則選擇性地將其添加到searchResults數組:

for (NSString *currentString in [[self contentsList] valueForKey:@"title"]) 
{ 
    … 
    [[self searchResults] addObject:currentString]; 
} 

這意味着searchResults是包含contentList陣列,其中不能自動與相應的字典的標題列表的陣列。

好像你要保持原有的字典,因爲你已經嘗試創建一個字典:

// NSDictionary *dic= [[NSDictionary alloc]allKeysForObject:searchResults]; 

,並在另一種方法,你想取得相應site鍵的值:

NSString *arraySite = [[[self searchResults] objectAtIndex:indexPath.row] 
    valueForKey:@"site"]; 

如上所述,您的searchResults包含表示標題的字符串列表。當你從這個數組中獲得一個元素時,它只是一個字符串 - 因此-valueForKey:@"site"沒有任何意義,而Cocoa會警告你一個字符串不是密鑰site的鍵值兼容。

一個解決方案

從我可以告訴,你應該存儲在您的searchResults陣列,原來的字典從plist文件讀取。在-handleSearchForTerm:,請執行下列操作:

for (NSDictionary *currentSite in [self contentsList]) 
{ 
    NSString *title = [currentSite objectForKey:@"title"]; 
    if ([title rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound) 
    { 
     [[self searchResults] addObject:currentSite]; 
    } 
} 

現在searchResults每個元素都是含有sitetitle字典。

-tableView:didSelectRowAtIndexPath:,用字典,以獲得相應site

- (void)tableView:(UITableView *)tableView 
    didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 

    NSDictionary *selectedSite = [[self searchResults] objectAtIndex:indexPath.row]; 
    NSString *siteStringURL = [selectedSite objectForKey:@"site"]; 
    // or, if you prefer everything in a single line: 
    // NSString *siteStringURL = [[[self searchResults] objectAtIndex:indexPath.row] objectForKey:@"site"]; 

    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:siteStringURL]]]; 
    [self performSelector:@selector(showSearch:) withObject:nil afterDelay:0]; 
} 
+0

驚人!!有效!謝謝你的解釋。 – Alby 2011-04-28 01:57:09