【问题标题】:NSDictionary is treated as a boolean - can't debugNSDictionary 被视为布尔值 - 无法调试
【发布时间】:2013-01-09 08:17:22
【问题描述】:
NSDictionary *tokenData = [[responseDict objectForKey:@"data"] objectForKey:@"multipass"];
dispatch_async(dispatch_get_main_queue(), ^{
    NSString *card = [NSString stringWithFormat:@"%@-%@",
        [[UserAccount sharedInstance] cardNumber],
        [tokenData objectForKey:@"CardPhoneToken"]]; //<-- problem
});

从昨天开始,我一直在与这行代码作斗争。我正在从服务器获取 JSON 提要,我的问题是,有十分之一的 tokenData 返回 0 而不是 Dictionary我不知道为什么。当它以0 返回时,它也被编译器视为布尔值(也不知道为什么),我收到错误-[NSCFBoolean objectForKey:]: unrecognized selector sent to instance 0x81aa20

我试过做这样的事情 if(!tokenData) { NSLog(@"This is going to crash"); } 但是当tokenData 返回0 时,if 不会被调用。

esponseDict JSON 我得到: { code = 200; data = { multipass = { CardPhoneBarcodeToken = 562431; CardPhoneToken = 23221; errorMessage = ""; operationResult = 0; }; }; }

这是崩溃前的样子:{ code = 200; data = { multipass = 0; }; }

更新:如果tokenData 不是NSDictionary,我已经设法采取措施,现在我面临else 部分的另一个问题。如果 tokenData 不是 NSDictionary ,我该如何重新加载?我尝试调用 *tokenData = [[responseDict objectForKey:@"data"] objectForKey:@"multipass"];在 else 里面,但我不断得到 tokenData = 0 谢谢

【问题讨论】:

  • 能否请您 psot json 或请您 NSLog 响应字典
  • multipass 对象也是字典吗?看来您正在从 data 字典中取出 NSNumber
  • 这是崩溃前的样子:{ code = 200; data = { multipass = 0; }; }

标签: ios objective-c xcode debugging


【解决方案1】:

我会在解析之前检查tokenData 是否为NSDictionary

-(void)loadData
{
    NSDictionary *tokenData = [[responseDict objectForKey:@"data"] objectForKey:@"multipass"];
    dispatch_async(dispatch_get_main_queue(), ^{
        NSString *cardPhoneToken = @"";
        if( [tokenData isKindOfClass:[NSDictionary class]] ){
            retryCount = 0;
            cardPhoneToken = [tokenData objectForKey:@"CardPhoneToken"];
        } else {
            NSLog(@"failed to load data, retrying...");
            retryCount++;
            if( retryCount < 5 ){
                [self loadData];
                return;
            } else {
                NSLog(@"failed after 5 retries");
            }

        }
        NSString *card = [NSString stringWithFormat:@"%@-%@",
                          [[UserAccount sharedInstance] cardNumber],
                          cardPhoneToken];

    });
}

【讨论】:

  • 您的代码有效,谢谢,但现在我面临else 部分的另一个问题。如果不是 NSDictionary ,我该如何重新加载 tokenData ?我尝试在 else 中调用 *tokenData = [[responseDict objectForKey:@"data"] objectForKey:@"multipass"];,但我不断收到 tokenData = 0
  • 我已经更新了我的答案并添加了重试功能。我使用了 NSInteger retryCount;为它。
  • 如果您真的可以预期响应会发生变化,那么从 Web 服务重新加载输入数据的方式会起作用。如果它是相当随机的“十分之一”,正如你所说,出于任何原因,那么重新加载可能会有所帮助。如果由于基础数据或其他原因在该点返回 0,您不能期望在几秒钟内更改,那么这种方法只会通过一遍又一遍地重复相同的事情来浪费时间,直到您最终不得不处理这种情况无论如何。
  • Hermann 有一个很好的观点。您可能想调查或联系网络服务所有者,了解它返回 0 的原因
  • 我收到EXC_BAD_ACCESS (code=1, address = 0x8900107f) when trying to [self myMethod];
【解决方案2】:

听起来很熟悉。 :)

将块更改为:

^{
    NSString *card;
    if ([tokenData isKindOfClass [NSDictionary class]) {

      card = [NSString stringWithFormat:@"%@-%@",
          [[UserAccount sharedInstance] cardNumber],
          [tokenData objectForKey:@"CardPhoneToken"]]; // <<-- No Problem anymore
     } else {
       // deal with the situation. Probably do: 
      card = [NSString stringWithFormat:"%@-no phone number given", [UserAccount sharedInstance] cardNumber]];
}

替代方案:

^{
    id cardPhoneToken;
    if ([tokenData]) {
       cardPhoneToken = [tokenData objectForKey:@"CardPhoneToken"];
    } else {
       cardPhoneToken = @"no Phone Token"; // Or what ever you think is appropriate
    }
    NSString *card = [NSString stringWithFormat:@"%@-%@",
        [[UserAccount sharedInstance] cardNumber],
        cardPhoneToken]; // <<-- No Problem anymore

}

【讨论】:

  • 当我发现tokenData 不是NSDictionary 我需要处理它时,您可以在我更新的问题中看到。我的问题是,我如何“重新加载”tokenData 以获得NSDictionary?我应该再打电话给NSDictionary *tokenData = [[responseDict objectForKey:@"data"] objectForKey:@"multipass"]; 吗?也许在while 内,以确保它是NSDictionary
  • 当我尝试做这样的事情时:while (![tokenData isKindOfClass:[NSDictionary class]]) { tokenData = [[responseDict objectForKey:@"data"] objectForKey:@"multipass"] ; } 我收到错误Variable is not assignable (missing __block type specifier)
  • 您无法真正“重新加载”,因为此时您的 JSON 输入中没有关联数组(=字典)。您将以某种方式将此视为例外。您可以通过指定一个字典来“伪造”字典。但这可能没什么帮助,我猜。
  • 重新发表您的第二条评论。您建议的 while 循环肯定会永远运行。除非,也许,NSDictionary 的内容被另一个线程更改。但这仍然不是任何聪明的设计。
猜你喜欢
  • 1970-01-01
  • 2016-08-29
  • 2012-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-08
  • 1970-01-01
  • 2012-12-03
相关资源
最近更新 更多