0

我有一个 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
4

0 回答 0