我有一个CoreData模型,它具有非标准属性作为成员。所以我有一个NSValueTransformer的子类将对象转换为NSData并返回。该成员有2个类型为NSNumber ... max和min的属性。我使用标准属性声明实现它们,让编译器合成它们的访问器,所以我假设一切都符合KVC。
如果我尝试将max或min绑定到NSTextCell(是的,NSTextCell上有一个数字格式化器),我可以编辑这些值,认为发生了一些事情,但是当我保存我的managedObjectContext并重新启动应用程序时,这些对象的初始值正在显示。
在该属性的CoreData模型中(将其命名为timeRange),我将其值变换器设置为正确的值,但似乎绑定仅在一个方向上工作。我似乎无法编辑这些值,让他们回到模型。
相比之下,具有timeRange属性的对象也具有简单的数字属性(因为我希望确保我有修改数字属性的机制),并且这些更改会传播到持久存储。
问题是,我做错了什么?我的实施可能缺少什么?我假设一旦你在非标准属性上指定了一个值转换器(在该属性的Core Data模型编辑器中),你就可以在其他任何地方使用该属性,就像它假设的那样,在本例中为SCTimeRange,不是NSData。
所以,如果这是真的,并且我的模型有一个SCTimeRange类型的属性,为什么我不能设置它非常简单的NSNumber属性?它是否与NSTextCell上的Number Formatter没有绑定到其他任何东西有关?即专栏不知道那个?
@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