使用allKeys时应用程序崩溃,是因为只有一个对象吗?

时间:2012-01-09 03:49:50

标签: iphone xcode exception error-handling nsdictionary

我无法弄清楚为什么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";
            }
        );
    };
};
}

3 个答案:

答案 0 :(得分:3)

在第一个示例中,您正在遍历一个字典数组,因此,NSArray *keys = [roster2 allKeys];正在调用数组。但是,在第二个示例中,您只有一个字典。它不是不是字典数组。所以你的循环for (NSDictionary *roster2 in nextArray)正在遍历你的字典的键,它们只是字符串,而不是数组。因此,错误。

首先,您的命名令人困惑。名为NSDictionary的{​​{1}}?试试这个:

nextArray

答案 1 :(得分:0)

不,这是因为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];
    }
}

答案 2 :(得分:0)

错误消息包含您需要知道的所有内容:

[__NSCFString allKeys]: unrecognized selector

这意味着您尝试在allKeys的实例上调用方法NSString

让我们看看你拨打allKeys的地方:

for (NSDictionary *roster2 in nextArray) {
    NSArray *keys = [roster2 allKeys];

roster2是NSString的一个实例,而不是NSDictionary。您希望nextArray包含NSDictionary个对象,但它包含NSString个对象。