9

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" ];

2 番目にクラッシュし、次のarchiveRootObjectメッセージがコンソールに出力されます。

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSKeyedArchiver encodeValueOfObjCType:at:]: this archiver cannot encode structs'
4

3 に答える 3

19

わかりました、トム、オタクの準備はできていますか? 私はこの若いホイッパースナッパーの世界では「年上の」男です。しかし、私は C についていくつかのことを覚えています。私は単なるオタクです。

とにかく、これには微妙な違いがあります。

typedef struct { double d1, d2; } Foo1;

この:

typedef struct Foo2 { double d1, d2; } Foo2;

1 つ目は、無名構造への型エイリアスです。2 番目は への型エイリアスstruct Foo2です。

現在、のドキュメントに@encodeは次のように記載されています。

typedef struct example {
    id   anObject;
    char *aString;
    int  anInt;
} Example;

{example=@*i}for both @encode(example)orになり@encode(Example)ます。したがって、これ@encodeは実際の構造体タグを使用していることを意味します。匿名構造体へのエイリアスを作成する typedef の場合、常に'@encodeを返すように見えます?

これをチェックしてください:

NSLog(@"Foo1: %s", @encode(Foo1));
NSLog(@"Foo2: %s", @encode(Foo2));

とにかく、CLLocationCoordinate2D がどのように定義されているか推測できますか? うん。当たってるよ。

typedef struct {
CLLocationDegrees latitude;
CLLocationDegrees longitude;
} CLLocationCoordinate2D;

これについてバグレポートを提出する必要があると思います。@encode匿名構造体にエイリアス typedef を使用しないために壊れているか、CLLocationCoordinate2D を完全に型指定する必要があるため、匿名構造体ではありません。

于 2012-09-06T02:04:17.310 に答える
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 };
    ...
于 2013-08-25T10:26:16.793 に答える
0

これ@encodeは、CLLocationCoordinate2D がチョークするためです。

NSLog(@"coords %@; type: %s", coords, @encode(CLLocationCoordinate2D));収量coords ( "<00000000 00405e40 00000000 00804440>" ); type: {?=dd}

于 2012-09-06T00:09:06.927 に答える