メンバーとして非標準属性を持つ CoreData モデルがあります。したがって、オブジェクトを NSData に変換して戻すための NSValueTransformer のサブクラスがあります。このメンバーには、型 NSNumber の 2 つのプロパティがあります... max と min。標準のプロパティ宣言を使用してそれらを実装し、コンパイラにそれらのアクセサーを合成させるので、すべてが KVC 準拠であると想定しています。
max または min を NSTextCell にバインドしようとすると (そうです、NSTextCell には数値フォーマッターがあります)、何かが起こったと考えてこれらの値を編集できますが、managedObjectContext を保存してアプリを再起動すると、init 値のみが表示されます。それらのオブジェクトが表示されています。
その属性の CoreData モデル (timeRange と呼びます) で、値トランスフォーマーを正しいものに設定しましたが、バインドは一方向にしか機能していないようです。これらの値を編集してモデルに戻すことはできないようです。
対照的に、timeRange 属性を持つオブジェクトには単純な数値属性もあり (数値属性を変更するメカニズムが機能していることを確認したかったため)、これらの変更は永続ストアに伝達されます。
問題は、私が間違っていることは何ですか? 私の実装には何が欠けているのでしょうか? 非標準属性 (その属性のコア データ モデル エディター) に値変換を指定すると、他の場所でその属性を想定どおりに操作できると思います。この場合は 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