8

目前我正在编写一个应用程序(目标 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 可能为零:它们不是
  • PHP 生成无效 JSON:使用验证器检查
  • null 值:其他表没有问题

有人有想法吗?

4

3 回答 3

11

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

  1. 将转义的 Unicode 转换为真正的 Unicode 字符。试试这个答案
  2. 使用另一个 JSON 引擎,例如JSONKitJSONKit还声称比NSJSONSerialization.
于 2012-10-11T15:43:02.363 回答
4

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

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

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

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

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

于 2012-12-03T13:20:38.703 回答
1

今天刚刚测试了 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);
于 2014-04-24T16:40:47.897 回答