NSJSONSerialization导致EXC_BAD_ACCESS

时间:2012-10-11 14:54:36

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

目前我正在编写一个应用程序(目标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;

}

该程序总是在EXC_BAD_ACCESS错误的位置崩溃,该行显示self.jsonSerializationResult和Instruments表示已检测到Zombie。我知道这意味着我发送消息的对象是零,但我无法找到如何解决它...这就是乐器所说的:

#   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值:其他表格没有问题

有人有想法吗?

3 个答案:

答案 0 :(得分:11)

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

  1. 将转义的Unicode转换为真正的Unicode字符。试试this SO answer
  2. 使用其他JSON引擎,例如JSONKitJSONKit也声称比NSJSONSerialization更具效果。

答案 1 :(得分:4)

我知道这个问题已得到解答,但我认为一些初学者可能会遇到与我相同的问题并被提出来。

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

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

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

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

答案 2 :(得分:1)

今天刚刚测试了NSJSONSerialization。使用iOS 7.1。这是工作。没有发现问题。看起来Apple修复了这个问题。

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);