Objective c 为什么我的NSColor课程是NSCONSTRETEDATA?

Objective c 为什么我的NSColor课程是NSCONSTRETEDATA?,objective-c,cocoa,core-data,Objective C,Cocoa,Core Data,在数据模型中,我将颜色定义为可转换属性,并为其指定了ColorTransformer。它可以工作,在同一个转换器的帮助下,我可以将它绑定到ColorPicker,保存并打开文档。 但当我尝试从代码访问它时: NSColor * color = corner.color; NSLog(@"Corner Color = %@\n%@", color, color.class); 我得到了NSMutableConcreteData的对象: bezierMesh[22164:730708] Corne

在数据模型中,我将颜色定义为可转换属性,并为其指定了ColorTransformer。它可以工作,在同一个转换器的帮助下,我可以将它绑定到ColorPicker,保存并打开文档。 但当我尝试从代码访问它时:

NSColor * color = corner.color;
NSLog(@"Corner Color = %@\n%@", color, color.class);
我得到了NSMutableConcreteData的对象:

bezierMesh[22164:730708] Corner Color = <040b7374 7265616d 74797065 6481e803 84014084 8484074e 53436f6c 6f720084 84084e53 4f626a65 63740085 84016301 84046666 66660183 6eb7613d 8357703e 3e8352b8 1e3f86>
NSConcreteMutableData
它会导致一个错误:

[NSKeyedUnarchiver initForReadingWithData:]: non-keyed archive cannot be decoded by NSKeyedUnarchiver

如何获取颜色NSColor?

这是我不久前写的一个
NSString
NSColor
转换器,它设计用于使用
NSSERDEFAULTS
中的RGB值存储颜色,因为我不喜欢
NSData
对象的默认用法:

StringColor Transformer.h:

@interface StringColourTransformer : NSValueTransformer

+ (NSString *)toString:(NSColor *)value;
+ (NSColor *)fromString:(NSString *)value;

@end
StringColor Transformer.m:

#import "StringColourTransformer.h"

@implementation StringColourTransformer

+ (NSString *)toString:(NSColor *)value {
    StringColourTransformer *transformer = [[StringColourTransformer alloc] init];
    NSString *str = [transformer reverseTransformedValue:value];
    return str;
}

+ (NSColor *)fromString:(NSString *)value {
    StringColourTransformer *transformer = [[StringColourTransformer alloc] init];
    NSColor *color = (NSColor *)[transformer transformedValue:value];
    return color;
}

+ (Class)transformedValueClass {
    return [NSColor class];
}

+ (BOOL)allowReverseTransformation {
    return YES;
}

- (id)transformedValue:(id)value {
    CGFloat r = 0.0, g = 0.0, b = 0.0, a = 1.0;

    // Only NSString classes are reverse-transformed
    if ([value isKindOfClass:[NSString class]]) {
        NSString *stringValue = (NSString *)value;
        sscanf([stringValue UTF8String],
#ifdef __x86_64
               "%lf %lf %lf %lf",
#else
               "%f %f %f %f",
#endif
               &r, &g, &b, &a);
    }

    return [NSColor colorWithCalibratedRed:r green:g blue:b alpha:a];
}

- (id)reverseTransformedValue:(id)value {
    CGFloat r = 0.0, g = 0.0, b = 0.0, a = 1.0;

    // Only NSColor classes are transformed
    if ([value isKindOfClass:[NSColor class]]) {
        NSColor *colourValue = (NSColor *)value;
        NSColor *converted = [colourValue colorUsingColorSpaceName:@"NSCalibratedRGBColorSpace"];
        [converted getRed:&r green:&g blue:&b alpha:&a];
    }

    return [NSString stringWithFormat:@"%.3f %.3f %.3f %.3f", r, g, b, a];
}

@end
如您所见,我提供了两个类方法,使从代码使用它变得更容易(
toString
fromString

它需要在应用程序生命周期的早期注册,以便用于在IB中转换值(这是从单个实例调用的,
\u stringcolortransformer
是一个实例变量):

转换非常简单,如下所示:

NSColor *colour = [StringColourTransformer fromString:@"1.0 1.0 0.0 1.0"];

注意:现在看代码,我可能会在
toString
/
fromString
方法中使用
[nsvaluetransformer-valueTransformerForName:
,而不是每次都创建一个新实例。它可能更便宜。

如果您的问题是如何在核心数据中存储UIColor(或OS X上的NSColor)对象…:NSValueTransformer不是必需的。core data modeler中的上述条目“Name”必须为空(现在有:“BMColorTransformer”)

实体(“MyData”)接口(相应地在OS X中使用NSColor)在代码中如下所示:

@interface MyData : NSManagedObject

// other attributes ...
@property (nonatomic, retain) UIColor * color;

@end
和实施

@implementation MyData

// other attributes ...
@dynamic color;

@end

但是,如果您不想将UIColor(或NSColor)存储为NSData(这会导致Sqlite数据库中出现BLOB格式),则需要编写一个NSValueTransformer,如@特洛伊木马发布的NSValueTransformer。他说“我不喜欢NSData的默认使用”-我想他更喜欢可读格式而不是二进制格式(??)。

这是我们在这里讨论的
NSValueTransformer
子类吗?如果是这样的话,您就不会从代码中使用它。BMColorTransformer是NSTransformer的一个子类。但也许有一个恰当的问题:如何在代码中使用NSTransformer子类?NSValueTransformer当然很简单。顺便说一句,我的BTColorTransformer有-(NSColor*)。。。而不是+(颜色*)。。。现在开始工作了!
@interface MyData : NSManagedObject

// other attributes ...
@property (nonatomic, retain) UIColor * color;

@end
@implementation MyData

// other attributes ...
@dynamic color;

@end