我有一个 CoreData 模型,它有一个非标准属性作为成员。所以我有一个 NSValueTransformer 的子类来将对象转换为 NSData 并返回。该成员有 2 个 NSNumber 类型的属性... max 和 min。我用标准的属性声明来实现它们,并让编译器合成它们的访问器,所以我假设一切都是 KVC 兼容的。
如果我尝试将 max 或 min 绑定到 NSTextCell(是的,NSTextCell 上有一个数字格式化程序),我可以编辑这些值,认为发生了一些事情,但是当我保存我的 managedObjectContext 并重新启动应用程序时,只有 init 值这些对象正在显示。
在该属性的 CoreData 模型(称为 timeRange)中,我将他的值转换器设置为正确的值,但似乎绑定仅在一个方向上起作用。我似乎无法编辑这些值,让它们回到模型中。
相比之下,具有 timeRange 属性的对象也有一个简单的数字属性(因为我想确保我得到了修改数字属性的机制),并且这些更改被传播到持久存储。
问题是,我做错了什么?我的实现可能缺少什么?我假设一旦您在非标准属性上指定了一个值转换器(在该属性的核心数据模型编辑器中),您就可以在其他任何地方使用该属性,就好像它应该是这样,在本例中为 SCTimeRange,不是 NSData。
所以,如果这是真的,并且我的模型有一个 SCTimeRange 类型的属性,为什么我不能设置它非常简单的 NSNumber 属性?它是否与 NSTextCell 上的数字格式化程序没有绑定到其他任何东西有关?即专栏不知道这一点?
@interface SCTimeRange : NSObject <NSCoding>
@property (nonatomic, strong) NSNumber *max;
@property (nonatomic, strong) NSNumber *min;
@end
@implementation SCTimeRange
- (id)init
{
self = [super init];
if (self) {
self.max = @(0.0f);
self.min = @(0.0f);
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
self.max = [aDecoder decodeObjectForKey:@"max"];
self.min = [aDecoder decodeObjectForKey:@"min"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
[aCoder encodeObject: self.max forKey:@"max"];
[aCoder encodeObject: self.min forKey:@"min"];
}
@end
和价值转换器:
@implementation SCTimeRangeTransformer
+(Class)transformedValueClass {
return [NSData class];
}
+ (BOOL)allowsReverseTransformation { return YES; }
-(id)transformedValue:(id)value {
if (value == nil) {
return nil;
} else if ([value isKindOfClass:[NSData class]]){
NSData *data = (NSData*)value;
return data;
}
else if ([value isKindOfClass:[SCTimeRange class]])
{
NSData *data = [NSKeyedArchiver archivedDataWithRootObject: (SCTimeRange*)value];
return data;
}
return nil;
}
- (id)reverseTransformedValue:(id)value
{
if (value == nil) {
return nil;
}
else if ([value isKindOfClass:[SCTimeRange class]])
{
return value;
}
else if ([value isKindOfClass:[NSData class]]){
NSData *data = (NSData*)value;
SCTimeRange *range = (SCTimeRange*)[NSKeyedUnarchiver unarchiveObjectWithData: data];
return range;
}
return nil;
}
@end