假设我有这样的模型:
#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
如您所见,我想在NSCoding序列化期间忽略anotherProp
,以及重新映射&#34; UUID&#34;到&#34; id&#34;。使用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
?
答案 0 :(得分:1)
您需要配置YapDatabase以使用Mantle。默认情况下,它将使用NSCoding。 (这就是为什么你会看到关于&#34; encodeWithCoder:&#34;的错误,因为该方法是NSCoding的一部分。)
查看YapDatabase的wiki文章,名为&#34; Storing Objects&#34;,它讨论了它如何使用序列化器/反序列化器块: https://github.com/yaptv/YapDatabase/wiki/Storing-Objects
基本上,当你分配/初始化你的YapDatabase实例时,你想要传递一个序列化器&amp;反序列化程序块,它使用Mantle执行序列化/反序列化。
另外,请参阅YapDatabase可用的各种init方法: https://github.com/yaptv/YapDatabase/blob/master/YapDatabase/YapDatabase.h
答案 1 :(得分:0)
这是我目前的方法,使用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
来显式设置不需要序列化的属性。积分转到Stephen O'Connor。