关于ios:JSON写错误 – 处理自定义类时的类型无效

JSON Write Error - Invalid type when dealing with custom classes

我有许多自定义类,从nsObject子类化,我正试图写入一个JSON文件。我的顶级类称为Survey,是一个单例类,它的一个属性是AddressArray,它包含另一个名为Address的类的实例。

在Survey的AddressArray中可以有任意数量的地址,我正试图将所有数据写入JSON文件。我的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
//In both Survey.m and Address.m, I have a method like this:
- (NSDictionary *)surveyDictionaryRepresentation
{
    NSMutableDictionary *dictionary = [NSMutableDictionary new];
    dictionary[@"name"] = [self name] ? : [NSNull null];
    dictionary[@"emailAddress"] = [self emailAddress] ? : [NSNull null];
    dictionary[@"addressArray"] = [self addressArray] ? : [NSNull null];
    dictionary[@"storage"] = [NSNumber numberWithInteger:[self storage]] ? : [NSNull null];
    dictionary[@"extraStops"] = [NSNumber numberWithBool:[self extraStops]] ? : [NSNull null];

    return [NSDictionary dictionaryWithDictionary:dictionary];
}

然后,在视图控制器中,我在viewdidload方法中有以下内容。

1
2
3
4
5
6
7
8
9
NSArray *surveys = @[[[Survey sharedInstance] surveyDictionaryRepresentation]];
NSMutableArray *addresses = [[NSMutableArray alloc]init];
for (Address *address in [[Survey sharedInstance]addressArray]){
    //What the hell was I thinking?
    [addresses addObject:[addressaddressDictionaryRepresentation]];
}
NSDictionary *dictionary = @{@"Survey": surveys, @"Address":addresses};
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:nil];
NSLog(@"%@", [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]);

现在,我得到以下错误:由于未捕获异常"nsInvalidArgumentException",正在终止应用程序,原因:"JSON写入(地址)中的类型无效"

我明白为什么会有问题。由于包含地址实例的AddressArray正在进行调查,因此将地址数据添加到为调查创建的JSON对象中似乎存在问题。我不知道该如何解决这个问题。在使用断点单步执行程序之后,我看到崩溃发生在它试图执行行:NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:nil];之后。

为了实现它的价值,我在遍历地址数组并在其内容上运行AddressDictionaryRepresentation方法之后,对它进行了nslog,它记录得很好,完美地显示了所有属性和所有值。我只是不能把它放到JSON文档中。有什么建议吗?非常感谢您的帮助。

编辑:地址数组日志的前几行:

1
2
3
4
5
6
7
  2015-02-18 11:21:29.122 [70958:920733] (
    {
    aCCOI ="-1";
    aCfloorNumber ="<null>";
    activity = 0;
    addressType ="-1";
    allowedToReserveDock ="-1";

edit 2:survey.m中唯一的其他代码是建立singleton的代码:+(InstanceType)共享实例{静态调查*_实例;静态调度一旦启动;发送一次(&;oncetoken,,^{_ instance=[[survey alloc]init];(});返回实例;}

EdTe3:if([自地址数组]){nsmutablearray*地址=[[nsmutablearray alloc]init];for(address*address in[[survey sharedinstance]addressarray])。{[地址AddObject:[地址地址DictionaryPresentation]];}dictionary[@"AddressArray"]=[自地址数组];}否则{dictionary[@"AddressArray"]=[nsnull空];}


[self-address array]应返回JSON数组,而不是带有地址对象的数组。就像您在@"地址"字段中所做的那样:NSMutableArray *addresses = [[NSMutableArray alloc]init];
for (Address *address in [[Survey sharedInstance]addressArray]){
[addresses addObject:[addressaddressDictionaryRepresentation]];
}
返回nsmutableArray地址,使其设置为@"AddressArray"的值。那你就没事了。


在classx toDictionary方法中,我倾向于创建一个可变字典,然后根据需要插入每个实例值/属性。对于指向另一个类的指针,我调用该类的toDictionary方法。对于指向类对象数组的指针,我创建了一个可变数组,然后为数组的每个元素调用classy的toDictionary方法。

创建一个单独的toArray方法来处理一个classy数组是没有实际意义的,因为数组处理很容易"样板"直接在调用方法中进行编码。