【问题标题】:NSJSONSerialization results in EXC_BAD_ACCESSNSJSONSerialization 导致 EXC_BAD_ACCESS
【发布时间】:2012-10-02 06:57:41
【问题描述】:

目前我正在编写一个应用程序(目标 iOS 6,启用 ARC),它使用 JSON 进行数据传输,使用 Core Data 进行持久存储。 JSON 数据由 PHP 脚本通过 json_encode 从 MySQL 数据库生成。

我的问题是,对于某些表中的数据,以下代码会失败:

- (NSDictionary *)executeFetch:(NSString *)query
{
    NSURL *requesturl = [NSURL URLWithString:[query stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    NSError *dataError = nil;
    self.jsonData = [NSData dataWithContentsOfURL:requesturl options:kNilOptions error:&dataError];

    NSError *error = nil;
    self.jsonSerializationResult = [NSJSONSerialization JSONObjectWithData:self.jsonData options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&error];

    return self.jsonSerializationResult;

}

程序总是在显示 self.jsonSerializationResult 和 Instruments 显示检测到 Zombie 的行上出现 EXC_BAD_ACCESS 错误而崩溃。我知道这意味着我向其发送消息的某个对象是 nil,但我不知道如何修复它......这就是 Instruments 必须说的:

#   Address Category    Event Type  RefCt   Timestamp   Size    Responsible Library Responsible Caller
0   0xa1b8a70   CFString (mutable)  Malloc  1   00:01.603.081   32  Foundation  -[NSPlaceholderMutableString initWithBytesNoCopy:length:encoding:freeWhenDone:]
1   0xa1b8a70   CFString (mutable)  Release 0   00:01.603.137   0   Foundation  newJSONValue
2   0xa1b8a70   CFString (mutable)  Zombie  -1  00:01.603.259   0   Foundation  newJSONString

我的程序适用于除此之外的所有 JSON 输出:

{
   "termin":[
      {
         "termin_id":"17",
         "veranstaltung_id":"20",
         "beginn":"2012-09-28 17:00:00",
         "ende":"2012-09-28 18:00:00",
         "freie_pl\u00e4tze":null
      },
      {
         "termin_id":"18",
         "veranstaltung_id":"26",
         "beginn":"2012-09-28 19:00:00",
         "ende":"2012-09-28 20:00:00",
         "freie_pl\u00e4tze":null
      },
      {
         "termin_id":"19",
         "veranstaltung_id":"26",
         "beginn":"2012-09-28 21:00:00",
         "ende":"2012-09-28 22:00:00",
         "freie_pl\u00e4tze":null
      },
      {
         "termin_id":"20",
         "veranstaltung_id":"46",
         "beginn":"2012-09-28 19:00:00",
         "ende":"2012-09-28 20:00:00",
         "freie_pl\u00e4tze":null
      },
      {
         "termin_id":"24",
         "veranstaltung_id":"66",
         "beginn":"2012-09-28 22:00:00",
         "ende":"2012-09-28 22:30:00",
         "freie_pl\u00e4tze":"120"
      }
   ]
}

我想到了一些可能的错误来源,但似乎没有一个是负责任的:

  • jsonData 或 jsonSerializationResult 可能为 nil:它们不是
  • PHP 生成了无效的 JSON:使用验证器进行检查
  • null 值:其他表没有问题

有人有想法吗?

【问题讨论】:

    标签: xcode json ios6 exc-bad-access nsjsonserialization


    【解决方案1】:

    这看起来像是NSJSONSerialization 的错误/缺点。该问题是由转义的 unicode 字符(freie_pl\u00e4tze 而不是freie_plätze)引起的。你有两个选择 -

    1. 将转义的 Unicode 转换为真正的 Unicode 字符。试试this SO answer
    2. 使用另一个 JSON 引擎,例如 JSONKitJSONKit 也声称比 NSJSONSerialization 性能更高。

    【讨论】:

    • 非常感谢!这是我在检查失败数据和工作数据之间的差异时唯一没有改变的事情......令人惊讶的是,转义字符似乎只是字典键的问题,而不是值......
    • 顺便说一句,如果我使用 NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves 选项,我只会看到这个。这也是你的经历吗?
    • 您好,来自AFNetworking 代码 cmets。 :) 谢谢,真的很有帮助!
    • 我已经使用 JSONKit 多年了。现在该项目几乎死了(最近一次更新是在 2 年前)。这个 Apple 的 NSJSONSerialization 是否已修复?到目前为止有哪些替代方案? TouchJSON 被 Facebook SDK 使用。
    • iOS 7 中 NSJSONSerialization 的转义 unicode 字符已修复,请参阅 openradar.appspot.com/…
    【解决方案2】:

    我知道这个问题已经得到解答,但我认为一些初学者可能和我有同样的问题并被带到这个问题。

    EXC_BAD_ACCESS 消息是由格式错误的 JSON 引起的。因为我不小心为一个对象使用了相同的名称,这在将 JSON 转换为字典时会导致问题。

    令人讨厌的是,它没有出现格式错误。以下是导致问题的 JSON 示例:

    "levels" : {
        "level1": {
            ....
        },
        "level1": {
            ... << All objects should have different names. This should be called level2.
        },
        "level3": {
            ...
        }
    

    为了解决这个问题,我必须确保同一级别的所有对象都有不同的名称。

    【讨论】:

      【解决方案3】:

      今天刚刚测试了 NSJSONSerialization。使用 iOS 7.1。这是工作。没有发现问题。看起来苹果解决了这个问题。

      NSString* jsonString = @"{ \"freie_pl\\u00e4tze\":null}";
      
      NSData* jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
      
      NSError *error = nil;
      NSDictionary* jsonSerializationResult = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&error];
      
      NSLog(@"%@", jsonSerializationResult);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-27
        • 2016-11-19
        • 2011-04-14
        • 2017-03-15
        • 2014-09-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多