4

Mantle フレームワーク ( https://github.com/github/Mantle ) を使用して、構造体プロパティを持つクラスの NSCoding をサポートしたいと考えています。

typedef struct {
    int x;
    int y;
} MPoint;

typedef struct {
    MPoint min;
    MPoint max;
} MRect;


@interface MObject : MTLModel

@property (assign, nonatomic) MRect rect;

@end

@implementation MObject
@end

しかし、オンラインでMTLModel + NSCoding.mでクラッシュしようとすると[NSKeyedArchiver archiveRootObject:obj toFile:@"file"];- (void)encodeWithCoder:(NSCoder *)coder

case MTLModelEncodingBehaviorUnconditional:
    [coder encodeObject:value forKey:key];

Mantle は c-struct エンコーディング (およびデコーディング) をサポートしていますか? または、そのようなクラスの NSCoding プロトコルをカスタム実装する必要がありますか?

4

2 に答える 2

4

思ったより簡単でした:

  1. プロパティを除外+encodingBehaviorsByPropertyKey
  2. 手動エンコード/エンコード除外プロパティ

サンプル:

#pragma mark - MTLModel + NSCoding

- (id)initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];
    if (self) {
        self.rect = [[self class] mRectFromData:[coder decodeObjectForKey:@"rectData"]];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)coder {
    [super encodeWithCoder:coder];

    [coder encodeObject:[[self class] dataFromMRect:self.rect] forKey:@"rectData"];
}

+ (NSDictionary *)encodingBehaviorsByPropertyKey {
    NSDictionary *excludeProperties = @{
                                        NSStringFromSelector(@selector(rect)): @(MTLModelEncodingBehaviorExcluded)
                                        };
    NSDictionary *encodingBehaviors = [[super encodingBehaviorsByPropertyKey] mtl_dictionaryByAddingEntriesFromDictionary:excludeProperties];
    return encodingBehaviors;
}

#pragma mark - MRect transformations

+ (MRect)mRectFromData:(NSData *)rectData {
    MRect rect;
    [rectData getBytes:&rect length:sizeof(rect)];
    return rect;
}

+ (NSData *)dataFromMRect:(MRect)rect {
    return [NSData dataWithBytes:&rect length:sizeof(rect)];
}
于 2014-02-19T13:36:56.910 に答える
4

私の元のデータ構造は XML です (ええ、私は知っています):

  ...
  <Lat>32.062883</Lat>
  <Lot>34.782904</Lot>
  ...

MTLXMLAdapterに基づいて使用しましKissXMLたが、他のシリアライザーにどのように適用できるかがわかります。

+ (NSValueTransformer *)coordinateXMLTransformer {
    return [MTLValueTransformer reversibleTransformerWithBlock:^id(NSArray *nodes) {
        CLLocationCoordinate2D coordinate;
        for (DDXMLNode *node in nodes) {
            if ([[node name] isEqualToString:@"Lat"]) {
                coordinate.latitude = [[node stringValue] doubleValue];
            } else if ([[node name] isEqualToString:@"Lot"]) {
                coordinate.longitude = [[node stringValue] doubleValue];
            }

        }
        return [NSValue value:&coordinate
                 withObjCType:@encode(CLLocationCoordinate2D)];
    }];
}

必要に応じて追加できreverseBlockます。

于 2013-12-11T09:12:55.577 に答える