0

我目前有一个存储数据的核心数据数据库,我还希望将 NSColor 存储到其中,但它不接受 NSColor 作为对象。我的解决方案是将其作为字符串存储在数据库中,并在加载时将其读入 NSColor。我该怎么做?

例如,如果我有一种颜色,[NSColor redColor]我将如何将它存储在数据库中(作为字符串)然后检索它。这是一个基本示例,最终将是更复杂的 RGB 颜色。

谢谢。

4

5 回答 5

4

您应该考虑使用 NSData 作为在 Core Data 中存储不受支持的数据类型的容器。要将 NSColor 作为 NSData 访问,您需要将属性标记为可转换并创建可逆的 NSValueTransformer 类以将 NSColor 转换为 NSData。

有用的链接:非标准持久属性

于 2012-06-08T22:44:37.870 回答
3

我同意建议使用 NSData 在核心数据存储中存储颜色的答案。也就是说,有时将颜色存储在字符串中可能很有用,而且这当然不难做到。我建议在 NSColor 上创建一个类别:

@interface NSColor (NSString)
- (NSString*)stringRepresentation;
+ (NSColor*)colorFromString:(NSString*)string forColorSpace:(NSColorSpace*)colorSpace;
@end

@implementation NSColor (NSString)

- (NSString*)stringRepresentation
{
    CGFloat components[10];

    [self getComponents:components];
    NSMutableString *string = [NSMutableString string];
    for (int i = 0; i < [self numberOfComponents]; i++) {
        [string appendFormat:@"%f ", components[i]];
    }
    [string deleteCharactersInRange:NSMakeRange([string length]-1, 1)]; // trim the trailing space
    return string;
}

+ (NSColor*)colorFromString:(NSString*)string forColorSpace:(NSColorSpace*)colorSpace
{
    CGFloat components[10];    // doubt any color spaces need more than 10 components
    NSArray *componentStrings = [string componentsSeparatedByString:@" "];
    int count = [componentStrings count];
    NSColor *color = nil;
    if (count <= 10) {
        for (int i = 0; i < count; i++) {
            components[i] = [[componentStrings objectAtIndex:i] floatValue];
        }
        color = [NSColor colorWithColorSpace:colorSpace components:components count:count];
    }
    return color;
}

@end

我已经检查了上面的代码是否按照宣传的方式编译和工作。一个小示例程序会产生适当的输出:

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        NSLog(@"Red is: %@", [[NSColor redColor] stringRepresentation]);
        NSLog(@"Cyan is: %@", [[NSColor cyanColor] stringRepresentation]);
        NSLog(@"Read in: %@", [NSColor colorFromString:[[NSColor redColor] stringRepresentation]
                                         forColorSpace:[NSColorSpace deviceRGBColorSpace]]);
    }
    return 0;
}

输出:

Red is: 1.000000 0.000000 0.000000 1.000000
Cyan is: 0.000000 1.000000 1.000000 1.000000
Read in: NSCustomColorSpace Generic RGB colorspace 1 0 0 1

将颜色空间存储在字符串中可能是有意义的,因此当您从字符串转到颜色时不必指定它。再说一次,如果您只是要存储这些字符串并再次读取它们,那么无论如何您都应该使用 NSData 。如果您需要将颜色写入某种人类可读的文件,或者可能作为调试辅助,使用字符串会更有意义。

于 2012-06-08T23:25:53.443 回答
2

NSColor支持NSCoding协议,因此您可以使用该-encodeWithCoder:方法将其保存到存档中,您可以使用-initWithCoder:从存档中加载它。

于 2012-06-08T22:43:29.743 回答
0

属性列表不存储颜色,Apple 建议您将它们存储为 NSData 而不是 NSString,您可能应该这样做。请在此处查看 Apple 的说明。

于 2012-06-08T22:46:10.023 回答
0

以下是用于将 a 转换NSColor为 和从NSString. 此示例假设我们使用的是 RGB 颜色空间,但它可以很容易地适应其他颜色空间。例如,NSStringFromColor()可以在字符串中包含颜色空间,并在转换回NSColorFromString().

用法:

NSString *theColorString = NSStringFromColor(theColor);
NSColor *theColor = NSColorFromString(theColorString);

功能:

NSString *NSStringFromColor(NSColor *theColor)
{
    CGFloat red, green, blue, alpha;
    [theColor getRed:&red green:&green blue:&blue alpha:&alpha]; // assumes RGB color space
    NSString *theColorString = [NSString stringWithFormat:@"%f %f %f %f",red,green,blue,alpha];
    return theColorString;
}

NSColor *NSColorFromString(NSString *theColorString)
{
    if ( theColorString.length == 0 ) {
        theColorString = @"0.9 0.9 0.95 1.0"; // a default color
    }
    NSArray <NSString *> *theColors = [theColorString componentsSeparatedByString:@" "];
    if ( theColors.count == 4 ) { // sanity
        // unpack the color
        NSColor *theColor = [NSColor colorWithSRGBRed:theColors[0].floatValue
                                                green:theColors[1].floatValue
                                                 blue:theColors[2].floatValue
                                                alpha:theColors[3].floatValue];
        return theColor;
    }
    return nil; // theColorString format error
}
于 2020-08-18T06:48:05.820 回答