0

假设我有这样的模型:

#import <Mantle/Mantle.h>
#import "MyCustomObject.h"
@interface MyModel : MTLModel <MTLJSONSerializing>
@property (nonatomic, copy, readonly) NSString *UUID;
@property (nonatomic, copy) NSString *someProp;
@property (nonatomic, copy) MyCustomObject *anotherProp;
@end

#import "MyModel.h"
@implementation MyModel
+ (NSDictionary *)JSONKeyPathsByPropertyKey
{
        return @{
            @"UUID": @"id",
            @"anotherProp": NSNull.null
    };
}
}
@end

如您所见,我想anotherProp在 NSCoding 序列化期间忽略,并将“UUID”重新映射到“id”。使用 YapDatabase,我做了一个

[transaction setObject:myModelObj forKey:@"key_1" inCollection:@"my_collection"]

anotherProp但尽管有我的自定义方法,它仍会尝试序列化JSONKeyPathsByPropertyKey,导致此错误:

*** Caught exception encoding value for key "anotherProp" on class MyModel: -[YapDatabase encodeWithCoder:]: unrecognized selector sent to instance 0xc989630

我是否需要编写自定义序列化程序才能使用 YapDatabase JSONKeyPathsByPropertyKey

4

2 回答 2

1

这是我目前使用MTLModel扩展来使这个“正常工作”而不需要序列化程序或任何东西的方法。如果有序列化器实现或更好的东西,请告诉我。否则,此代码可以挽救生命:

// JSONEncodableMTLModel.h
#import <Foundation/Foundation.h>
#import "Mantle.h"

@interface JSONEncodableMTLModel : MTLModel <MTLJSONSerializing>    
+ (NSSet*)propertyKeysToExcludeInDictionaryValue;
@end

//  JSONEncodableMTLModel.m
#import "JSONEncodableMTLModel.h"
#import <objc/runtime.h>

@implementation JSONEncodableMTLModel

+(NSDictionary *)JSONKeyPathsByPropertyKey {
    return @{};
}

+ (NSSet*)propertyKeysToExcludeInDictionaryValue
{
    return [NSSet set];
}

// this is required to ensure we don't have cyclical references when including the parent variable.
+ (NSSet *)propertyKeys {
    NSSet *cachedKeys = objc_getAssociatedObject(self, HSModelCachedPropertyKeysKey);
    if (cachedKeys != nil) return cachedKeys;

    NSMutableSet *keys = [NSMutableSet setWithSet:[super propertyKeys]];

    NSSet *exclusionKeys = [self propertyKeysToExcludeInDictionaryValue];
    NSLog(@"Caching Your Property Keys");
    [exclusionKeys enumerateObjectsUsingBlock:^(NSString *propertyKey, BOOL *stop) {
        if([keys containsObject: propertyKey])
        {
            [keys removeObject: propertyKey];
        }
    }];

    // It doesn't really matter if we replace another thread's work, since we do
    // it atomically and the result should be the same.
    objc_setAssociatedObject(self, HSModelCachedPropertyKeysKey, [keys copy], OBJC_ASSOCIATION_COPY);

    return keys;
}

@end

propertyKeysToExcludeInDictionaryValue使用此代码,我可以通过覆盖任何作为子类的模型来显式设置不需要序列化的属性。归功于斯蒂芬奥康纳

于 2014-05-28T06:15:55.013 回答
1

您需要配置 YapDatabase 以使用 Mantle。默认情况下,它将使用 NSCoding。(这就是为什么您会看到有关“encodeWithCoder:”的错误,因为该方法是 NSCoding 的一部分。)

看看 YapDatabase 的 wiki 文章,标题为“Storing Objects”,其中讨论了它如何使用序列化器/反序列化器块: https ://github.com/yaptv/YapDatabase/wiki/Storing-Objects

基本上,当您分配/初始化 YapDatabase 实例时,您需要传递一个使用 Mantle 执行序列化/反序列化的序列化器和反序列化器块。

此外,请参阅 YapDatabase 可用的各种初始化方法: https ://github.com/yaptv/YapDatabase/blob/master/YapDatabase/YapDatabase.h

于 2014-05-23T21:50:25.997 回答