开发者

Problem with NSMutableArray and valueforkey

开发者 https://www.devze.com 2023-03-01 08:18 出处:网络
I use a plist file to get a list of site which are displayed in a tableview The plist looks like this:

I use a plist file to get a list of site which are displayed in a tableview

The plist looks like this:

   <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>

I display this without problem:

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

*The problem is when I try to search in the content and I want to get the valueforkey @"site" from the search result to use it in 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];
            }
        }
    }

}

The didSelectRowAtIndexPath is used to open the site in a 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];

}

E开发者_如何转开发RROR I GET :

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


The Basics

When you read the array from that plist, the array looks like the following:

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

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

    …
)

It is an array whose elements are dictionaries, each dictionary containing two keys and their corresponding values.

When you use the KVC method -valueForKey: on the array passing the key title, it returns another array whose elements are the values corresponding to that key:

(
    "Yahoo",
    "Google",
    …
)

The resulting array doesn’t hold a reference to the original array.

The Problem

In -handleSearchForTerm:, you get an array containing only the titles from the original array. For each title, you selectively add it to the searchResults array:

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

This means that searchResults is an array containing a list of titles which are not automatically related to the corresponding dictionaries in the contentList array.

It seems like you want to keep the original dictionary because you’ve tried to create a dictionary:

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

and, in another method, you’re trying to obtain the value corresponding to the site key:

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

As mentioned, your searchResults contains a list of strings representing titles. When you obtain an element from this array, it’s only a string — hence -valueForKey:@"site" doesn’t make sense, and Cocoa warns you that a string is not key-value compliant for the key site.

One Solution

From what I can tell, you should be storing, in your searchResults array, the original dictionary read from the plist file. In -handleSearchForTerm:, do the following:

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

Now every element in searchResults is a dictionary containing both site and title.

In -tableView:didSelectRowAtIndexPath:, use the dictionary to obtain the corresponding 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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号