核心数据数据模型:UIColor的属性类型

ind*_*gie 6 iphone cocoa-touch core-data objective-c

我刚刚开始使用Core Data,现在我正在构建我的数据模型.我的实体需要一个UIColor属性,但属性的类型下拉列表没有这个选项.我将它设置为Undefined还是什么?

谢谢

Ros*_*one 20

我将解释我在Dave Mark和Jeff LeMarche撰写的更多iPhone 3开发中找到的明确答案:

通常我们可以将transformable属性的变换器类保留为默认值NSKeyedUnarchiveFromData,并且可以完成,但在这种情况下我们不能因为UIColor不符合NSCoding并且不能使用NSKeyedArchiver.我们必须手动编写一个值转换器来处理转换.

向您的实体添加属性并调用属性"color"或您希望的任何名称.将其类型设置为Transformable.将其"Value Transformer Name"设置为UIColorRGBValueTransformer.请注意,数据模型编辑器不验证值转换器名称:要确保它是有效的类,请仔细键入.

创建一个新文件,子类NSObject,并将其命名为UIColorRGBValueTransformer.m.

单击UIColorRGBValueTransformer.h并将超类从NSObject更改为NSValueTransformer.此外,#import <Foundation/Foundation.h>改为#import <UIKit/UIKit.h>,因为UIColor是一部分UIKit,不是Foundation.

现在,在UIColorRGBValueTransformer.m,我们需要实现四个方法,使我们的价值变压器类实例转换的UIColorNSData,反之亦然.在UIColorRGBValueTransformer.m中包含以下代码:

#import "UIColorRGBValueTransformer.h"

@implementation UIColorRGBValueTransformer

// Here we override the method that returns the class of objects that this transformer can convert.
+ (Class)transformedValueClass {
    return [NSData class];
}

// Here we indicate that our converter supports two-way conversions.
// That is, we need  to convert UICOLOR to an instance of NSData and back from an instance of NSData to an instance of UIColor.
// Otherwise, we wouldn't be able to beth save and retrieve values from the persistent store.
+ (BOOL)allowsReversTransformation {
    return YES;
}

// Takes a UIColor, returns an NSData
- (id)transfomedValue:(id)value {
    UIColor *color = value;
    const CGFloat *components = CGColorGetComponents(color.CGColor);
    NSString *colorAsString = [NSString stringWithFormat:@"%f,%f,%f,%f", components[0], components[1], components[2], components[3]];
    return [colorAsString dataUsingEncoding:NSUTF8StringEncoding];
}

// Takes an NSData, returns a UIColor
- (id)reverseTransformedValue:(id)value {
    NSString *colorAsString = [[[NSString alloc] initWithData:value encoding:NSUTF8StringEncoding] autorelease];
    NSArray *components = [colorAsString componentsSeparatedByString:@","];
    CGFloat r = [[components objectAtIndex:0] floatValue];
    CGFloat g = [[components objectAtIndex:1] floatValue];
    CGFloat b = [[components objectAtIndex:2] floatValue];
    CGFloat a = [[components objectAtIndex:3] floatValue];
    return [UIColor colorWithRed:r green:g blue:b alpha:a];
}

@end
Run Code Online (Sandbox Code Playgroud)

现在在另一个文件中,您可以包含一行代码,例如:

[self.managedObject setValue:color forKey:self.keyPath];
Run Code Online (Sandbox Code Playgroud)

无需在文件中导入UIColorRGBValueTransformer.h.

  • 虽然这确实有用,但应该注意到UIColor实际上符合NSCoding(与上面提到的相反)并且不需要特殊的变压器. (13认同)

Bar*_*ark 16

你可能想要的是一个可转换的属性.另请参阅"核心数据编程指南"中有关" 非标准持久属性 " 的部分.可转换属性在底层下面是二进制数据属性,但Core Data将自动使用NSValueTransformer您的规范来为您序列化和反序列化逻辑属性值.对于NSCoding符合要求的值,NSKeyedUnarchiveFromDataTransformerName(默认变换器)将起作用.

当然,Core Data无法索引,或者对于SQLite后端,无法对此可转换值进行查询.