NSMutableArray 和 valueforkey 的问题
我使用 plist 文件来获取在表视图中显示的站点列表
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.'
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];
}
ERROR 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.'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
基础知识
当您从该 plist 读取数组时,该数组如下所示:
它是一个其元素是字典的数组,每个字典包含两个键及其对应的值。
当您在传递键
title
的数组上使用 KVC 方法-valueForKey:
时,它会返回另一个数组,其元素是与该键对应的值:生成的数组不会t 保存对原始数组的引用。
问题
在
-handleSearchForTerm:
中,您得到一个仅包含原始数组中标题的数组。对于每个标题,您有选择地将其添加到searchResults
数组中:这意味着
searchResults
是一个包含标题列表的数组,这些标题不会自动与contentList
数组。看来您想保留原始字典,因为您尝试创建字典:
并且在另一种方法中,您尝试获取与
site
键对应的值:如上所述,您的
searchResults
包含表示标题的字符串列表。当你从这个数组中获取一个元素时,它只是一个字符串 - 因此-valueForKey:@"site"
没有意义,Cocoa 会警告你字符串不符合键值对关键站点
。一种解决方案
据我所知,您应该将从 plist 文件中读取的原始字典存储在
searchResults
数组中。在-handleSearchForTerm:
中,执行以下操作:现在
searchResults
中的每个元素都是包含site
和title
的字典。在
-tableView:didSelectRowAtIndexPath:
中,使用字典获取对应的site
:The Basics
When you read the array from that plist, the array looks like the following:
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 keytitle
, it returns another array whose elements are the values corresponding to that key: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 thesearchResults
array:This means that
searchResults
is an array containing a list of titles which are not automatically related to the corresponding dictionaries in thecontentList
array.It seems like you want to keep the original dictionary because you’ve tried to create a dictionary:
and, in another method, you’re trying to obtain the value corresponding to the
site
key: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 keysite
.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:Now every element in
searchResults
is a dictionary containing bothsite
andtitle
.In
-tableView:didSelectRowAtIndexPath:
, use the dictionary to obtain the correspondingsite
: