4

我想使用 Mantle 框架 ( https://github.com/github/Mantle ) 为我的类使用 struct 属性支持 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

但是当我试图[NSKeyedArchiver archiveRootObject:obj toFile:@"file"];让它在MTLModel+NSCoding.m中崩溃的时候,- (void)encodeWithCoder:(NSCoder *)coder就上线了

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

Mantle 是否支持 c-struct 编码(以及解码)或者我需要为此类类自定义实现 NSCoding 协议?

4

2 回答 2

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 回答
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 回答