JSON 写入错误 - 处理自定义时类型无效 类
JSON Write Error - Invalid type when dealing with custom classes
我有一些自定义的 classes,从 NSObject 子classed,我正试图写入一个 JSON 文件。我的顶层 class 称为 Survey,是一个单例,其属性之一是 addressArray,它包含另一个 class 称为 Address 的实例。
Survey 的 addressArray 中可以有任意数量的地址,我正在尝试将所有数据写入 JSON 文件。我的代码如下:
//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 方法中有以下内容。
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' 而终止应用程序,原因:'Invalid type in JSON write (Address)'
我明白为什么会有问题了。因为包含 Address 实例的 addressArray 在 Survey 中,所以将 Address 数据添加到为 Survey 创建的 JSON 对象时似乎存在问题。我不确定如何解决这个问题。使用断点单步执行程序后,我看到崩溃是在它尝试执行以下行后发生的:NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:nil];
为了它的价值,我在循环遍历地址数组后对地址数组进行了 NSLog,并在其内容上使用了 addressesDictionaryRepresentation 方法,它完美地记录了所有属性和所有值。我只是无法将其放入 JSON 文档中。有什么建议么?非常感谢您的帮助。
编辑:AddressArray 日志的前几行:
2015-02-18 11:21:29.122 [70958:920733] (
{
aCCOI = "-1";
aCfloorNumber = "<null>";
activity = 0;
addressType = "-1";
allowedToReserveDock = "-1";
编辑 2:Survey.m 中唯一的其他代码是建立单例的代码:
+ (实例类型)sharedInstance {
静态调查 *_instance;
静态dispatch_once_t一次令牌;
dispatch_once(&一次令牌, ^{
_instance = [[调查分配] init];
});
return_实例;
}
编辑3:
如果([自地址数组]){
NSMutableArray *addresses = [[NSMutableArray alloc]init];
对于(地址 * [[Survey sharedInstance]addressArray] 中的地址){
[地址addObject:[地址addressDictionaryRepresentation]];
}
dictionary[@"addressArray"] = [self addressArray];
} 别的 {
dictionary[@"addressArray"] = [NSNull null];
}
[self addressArray] 应该 return 一个 JSON 数组,而不是带有 Address 对象的数组。就像您对 @"Address" 字段所做的那样:
NSMutableArray *地址 = [[NSMutableArray alloc]init];
对于(地址 * [[Survey sharedInstance]addressArray] 中的地址){
[地址 addObject:[addressaddressDictionaryRepresentation]];<br>
}
Return NSMutableArray 地址,因此它被设置为 @"addressArray" 的值。那你应该没问题。
我倾向于在 ClassX toDictionary
方法中创建一个可变字典,然后适当地插入每个实例 value/property。对于指向另一个 class 的指针,我调用了 class 的 toDictionary
方法。对于指向 ClassY 对象数组的指针,我创建了一个可变数组,然后为数组的每个元素调用 ClassY 的 toDictionary
方法。
创建单独的 toArray
方法来处理 ClassY 数组没有实际意义,因为数组处理很容易 "boilerplate" 直接在调用方法中编写代码。
我有一些自定义的 classes,从 NSObject 子classed,我正试图写入一个 JSON 文件。我的顶层 class 称为 Survey,是一个单例,其属性之一是 addressArray,它包含另一个 class 称为 Address 的实例。
Survey 的 addressArray 中可以有任意数量的地址,我正在尝试将所有数据写入 JSON 文件。我的代码如下:
//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 方法中有以下内容。
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' 而终止应用程序,原因:'Invalid type in JSON write (Address)'
我明白为什么会有问题了。因为包含 Address 实例的 addressArray 在 Survey 中,所以将 Address 数据添加到为 Survey 创建的 JSON 对象时似乎存在问题。我不确定如何解决这个问题。使用断点单步执行程序后,我看到崩溃是在它尝试执行以下行后发生的:NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:nil];
为了它的价值,我在循环遍历地址数组后对地址数组进行了 NSLog,并在其内容上使用了 addressesDictionaryRepresentation 方法,它完美地记录了所有属性和所有值。我只是无法将其放入 JSON 文档中。有什么建议么?非常感谢您的帮助。
编辑:AddressArray 日志的前几行:
2015-02-18 11:21:29.122 [70958:920733] (
{
aCCOI = "-1";
aCfloorNumber = "<null>";
activity = 0;
addressType = "-1";
allowedToReserveDock = "-1";
编辑 2:Survey.m 中唯一的其他代码是建立单例的代码: + (实例类型)sharedInstance { 静态调查 *_instance; 静态dispatch_once_t一次令牌; dispatch_once(&一次令牌, ^{ _instance = [[调查分配] init]; }); return_实例; }
编辑3: 如果([自地址数组]){ NSMutableArray *addresses = [[NSMutableArray alloc]init]; 对于(地址 * [[Survey sharedInstance]addressArray] 中的地址){ [地址addObject:[地址addressDictionaryRepresentation]]; } dictionary[@"addressArray"] = [self addressArray]; } 别的 { dictionary[@"addressArray"] = [NSNull null]; }
[self addressArray] 应该 return 一个 JSON 数组,而不是带有 Address 对象的数组。就像您对 @"Address" 字段所做的那样:
NSMutableArray *地址 = [[NSMutableArray alloc]init];
对于(地址 * [[Survey sharedInstance]addressArray] 中的地址){
[地址 addObject:[addressaddressDictionaryRepresentation]];<br>
}
Return NSMutableArray 地址,因此它被设置为 @"addressArray" 的值。那你应该没问题。
我倾向于在 ClassX toDictionary
方法中创建一个可变字典,然后适当地插入每个实例 value/property。对于指向另一个 class 的指针,我调用了 class 的 toDictionary
方法。对于指向 ClassY 对象数组的指针,我创建了一个可变数组,然后为数组的每个元素调用 ClassY 的 toDictionary
方法。
创建单独的 toArray
方法来处理 ClassY 数组没有实际意义,因为数组处理很容易 "boilerplate" 直接在调用方法中编写代码。