我不明白xcode为什么继续抛出这个错误
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-
[__NSCFString allKeys]: unrecognized selector sent to instance 0x9367330'
每当我使用这个代码
NSDictionary *nextArray = [_classDictionary
valueForKeyPath:@"response.page_records.page_record"];
for (NSDictionary *roster2 in nextArray) {
NSArray *keys = [roster2 allKeys];
if ([keys containsObject:@"title"]){
[pageName addObject:[roster2 objectForKey:@"title"]];
}
if ([keys containsObject:@"id"]) {
[pageID addObject:[roster2 objectForKey:@"id"]];
}
}
在尝试调试它之后,我发现只有当键只有一个对象时才会抛出异常。例如,当"nextArray"是这样时:
(
{
"class_id" = 0001;
"id" = 1234;
"title" = "First Page";
},
{
"class_id" = 0002;
"id" = 12345;
"title" = Assignments;
}
)
代码运行时没有异常,但当代码只是时
{
"class_id" = 0001;
"id" = 1234;
"title" = "First Page";
}
引发了异常。为什么会发生这种情况?即使只有一个对象,关键帧仍然包含对象标题。为什么抛出这个异常还有其他想法吗?这和括号有关吗?(完全猜测)有没有更好的方法来调试真正发生的事情?
编辑:这是_userDictionary。有一个有序的objectforKey:@"title"数组并避免上述错误的最佳方法是什么?
response = {
"status" = ok;
"page_records" = {
"page" = 1;
"page_count" = 1;
"records_per_page" = 50;
"total_record_count" = 2;
"page_record" = (
{
"class_id" = 0001;
"id" = 1234;
"title" = "Test page";
},
{
"class_id" = 0002;
"id" = 12345;
"title" = "testing page 2";
}
);
};
};
}
在第一个例子中,您正在遍历一个字典数组,因此,NSArray *keys = [roster2 allKeys];
被调用到一个数组中。然而,在第二个示例中,您只有一个字典。这不是一个字典数组。因此,循环for (NSDictionary *roster2 in nextArray)
正在遍历字典的键,这些键只是字符串,而不是数组。因此,出现了错误。
首先,您的命名令人困惑。一个叫nextArray
的NSDictionary
?试试这个:
id *response = [_classDictionary valueForKeyPath:@"response.page_records.page_record"];
NSMutableArray *records;
if ([response isKindOfClass: [NSDictionary class]]) {
records = [[NSMutableArray alloc] init];
[records addObject: response];
}
else {
records = [NSMutableArray arrayWithArray: response];
}
for (NSDictionary *roster2 in records) {
NSArray *keys = [roster2 allKeys];
if ([keys containsObject:@"title"]){
[pageName addObject:[roster2 objectForKey:@"title"]];
}
if ([keys containsObject:@"id"]) {
[pageID addObject:[roster2 objectForKey:@"id"]];
}
}
错误消息包含您需要知道的所有信息:
[__NSCFString allKeys]: unrecognized selector
这意味着您正试图在NSString
的实例上调用方法allKeys
。
让我们看看您在哪里调用allKeys
:
for (NSDictionary *roster2 in nextArray) {
NSArray *keys = [roster2 allKeys];
roster2
是NSString的实例,而不是NSDictionary。您期望nextArray
包含NSDictionary
对象,但它却包含NSString
对象。
不,因为NSString
不响应allKeys
。控制台日志告诉您这一点——您需要更仔细地阅读它。
在NeXT风格的plists中,({})
定义了一个包含字典的数组。{}
定义只是一个字典。也就是说,这个:
{
"class_id" = 0001;
"id" = 1234;
"title" = "First Page";
}
与在结构上是否相同:
(
{
"class_id" = 0001;
"id" = 1234;
"title" = "First Page";
}
)
即使它们包含相同的信息。即使根数组中只有一个元素,您仍然需要告诉plist解析器那里有一个数组,因此您需要包括(
和)
,以便逻辑正确处理它。
编辑:考虑到您评论中的信息,解决方案不会那么简单。如果您的源数据是任意的,那么您需要检查数据的类型,看看它是NSArray
还是NSDictionary
,并对其进行适当的处理。例如:
id myData = [self plistFromArbitrarySource];
if (myData) {
if ([myData isKindOfClass: [NSArray class]]) {
for (NSDictionary *dict in myData) {
[self parseDictionary:dict];
}
} else if ([myData isKindOfClass: [NSDictionary class]]) {
[self parseDictionary:myData];
}
}