【问题标题】:Problem with NSMutableArray and valueforkeyNSMutableArray 和 valueforkey 的问题
【发布时间】:2011-04-27 22:53:14
【问题描述】:

我使用 plist 文件来获取在 tableview 中显示的站点列表

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 用于在 webView 中打开站点

- (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.'

【问题讨论】:

    标签: iphone xcode uiwebview nsmutablearray uisearchdisplaycontroller


    【解决方案1】:

    基础知识

    当您从该 plist 中读取数组时,该数组如下所示:

    (
        {
            "site"  = "http://yahoo.com",
            "title" = "Yahoo"
        },
    
        {
            "site"  = "http://google.com",
            "title" = "Google"
        },
    
        …
    )
    

    它是一个数组,其元素是字典,每个字典包含两个键及其对应的值。

    当您在传递键 title 的数组上使用 KVC 方法 -valueForKey: 时,它会返回另一个数组,其元素是与该键对应的值:

    (
        "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];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多