我不明白为什么我可以归档CGPoint
结构但不归档CLLocationCoordinate2D
结构。归档者有什么不同?
平台是iOS。我正在模拟器中运行,并没有尝试过该设备。
// why does this work:
NSMutableArray *points = [[[NSMutableArray alloc] init] autorelease];
CGPoint p = CGPointMake(10, 11);
[points addObject:[NSValue valueWithBytes: &p objCType: @encode(CGPoint)]];
[NSKeyedArchiver archiveRootObject:points toFile: @"/Volumes/Macintosh HD 2/points.bin" ];
// and this doesnt work:
NSMutableArray *coords = [[[NSMutableArray alloc] init] autorelease];
CLLocationCoordinate2D c = CLLocationCoordinate2DMake(121, 41);
[coords addObject:[NSValue valueWithBytes: &c objCType: @encode(CLLocationCoordinate2D)]];
[NSKeyedArchiver archiveRootObject:coords toFile: @"/Volumes/Macintosh HD 2/coords.bin" ];
我在第二个archiveRootObject
发生了崩溃,并且此消息将打印到控制台:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSKeyedArchiver encodeValueOfObjCType:at:]: this archiver cannot encode structs'
答案 0 :(得分:18)
无论如何,这之间有一个微妙的区别:
typedef struct { double d1, d2; } Foo1;
和此:
typedef struct Foo2 { double d1, d2; } Foo2;
第一个是匿名结构的类型别名。第二个是struct Foo2
的类型别名。
现在,@encode
的文档说明了以下内容:
typedef struct example {
id anObject;
char *aString;
int anInt;
} Example;
将导致{example=@*i}
或@encode(example)
@encode(Example)
。因此,这意味着@encode
正在使用实际的struct标记。对于为匿名结构创建别名的typedef,看起来@encode
始终返回?
'
检查出来:
NSLog(@"Foo1: %s", @encode(Foo1));
NSLog(@"Foo2: %s", @encode(Foo2));
无论如何,你能猜出CLLocationCoordinate2D是如何定义的吗?是的。你猜对了。
typedef struct {
CLLocationDegrees latitude;
CLLocationDegrees longitude;
} CLLocationCoordinate2D;
我认为您应该就此提交错误报告。 @encode
被破坏是因为它没有对匿名结构使用别名typedef,或者CLLocationCoordinate2D需要完全类型化,因此它不是匿名结构。
答案 1 :(得分:3)
要解决此限制,直到修复错误,只需分解坐标并重建:
- (void)encodeWithCoder:(NSCoder *)coder
{
NSNumber *latitude = [NSNumber numberWithDouble:self.coordinate.latitude];
NSNumber *longitude = [NSNumber numberWithDouble:self.coordinate.longitude];
[coder encodeObject:latitude forKey:@"latitude"];
[coder encodeObject:longitude forKey:@"longitude"];
...
- (id)initWithCoder:(NSCoder *)decoder
{
CLLocationDegrees latitude = (CLLocationDegrees)[(NSNumber*)[decoder decodeObjectForKey:@"latitude"] doubleValue];
CLLocationDegrees longitude = (CLLocationDegrees)[(NSNumber*)[decoder decodeObjectForKey:@"longitude"] doubleValue];
CLLocationCoordinate2D coordinate = (CLLocationCoordinate2D) { latitude, longitude };
...
答案 2 :(得分:0)
这是因为CLLocationCoordinate2D上的@encode
窒息
NSLog(@"coords %@; type: %s", coords, @encode(CLLocationCoordinate2D));
收益coords (
"<00000000 00405e40 00000000 00804440>"
); type: {?=dd}