NSMutableArray和valueforkey的问题

时间:2011-04-27 22:53:14

标签: iphone xcode uiwebview nsmutablearray uisearchdisplaycontroller

我使用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.'

1 个答案:

答案 0 :(得分:7)

基础知识

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

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

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

    …
)

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

在传递键-valueForKey:的数组上使用KVC方法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];
}