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