2010-02-21 188 views

回答

16

你可能想要的是一个可变形的属性。核心数据编程指南中的“Non-standard Persistent Attributes”部分请另外阅读。可转换属性在封面下是二进制数据属性,但核心数据将自动使用您的规范的NSValueTransformer为您逻辑属性值进行序列化和反序列化。对于符合NSCoding的值,NSKeyedUnarchiveFromDataTransformerName(这是默认的变压器)将执行此操作。

当然,核心数据无法编制索引,或者对于SQLite后端,可以针对此可转换值进行查询。

20

我会套用definitve答案我在更多iPhone 3开发发现由Dave马克和杰夫LeMarche:

通常我们会能够留下变形属性的变压器类作为默认,NSKeyedUnarchiveFromData,这样做,但在这种情况下,我们不能因为UIColor不符合NSCoding,并且不能使用NSKeyedArchiver存档。我们必须手动编写一个值转换器来处理转换。

为您的实体添加一个属性并调用属性“color”或任何您想要的名称。将其类型设置为可变形。将其“Value Transformer Name”设置为UIColorRGBValueTransformer。请注意,数据模型编辑器不验证值转换器名称:以确保它是有效的类,因此请仔细键入。

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

Click UIColorRGBValueTransformer.h并将超类从NSObject更改为NSValueTransformer。另外,将#import <Foundation/Foundation.h>更改为#import <UIKit/UIKit.h>,因为UIColorUIKit的一部分,而不是Foundation

现在UIColorRGBValueTransformer.m,我们需要实现四个方法,使我们的价值变压器类的实例UIColor转换为NSData,反之亦然。包括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 

现在,在另一个文件中,可以包括一行类似的代码:

[self.managedObject setValue:color forKey:self.keyPath]; 

,而无需导入UIColorRGBValueTransformer.h在文件。

+1

这个答案是惊人的,永远不会想通了这一点。一个微小的编辑“allowedReversTransformation”和“transfomedValue”拼写错误,但只修复了需要编辑的6个字母中的2个。 – rob5408 2011-05-26 04:16:47

+13

虽然这确实有效,但应该注意的是,UIColor确实符合NSCoding(与上面提到的相反)并且不需要特殊的变压器。 – rob5408 2011-06-10 16:50:43

3

是否可以将UIColor作为字符串存储为HEX(FFFFFF或其他Web安全颜色),然后当您阅读颜色时,将字符串转换为UIColor可以理解的格式?

3

将颜色属性指定为可转换名称ColorToDataTransformer后指定。 我们可以简单地生成MangatedObjectSubclass写变压器代码里面

//SampleEntity.h

#import <Foundation/Foundation.h> 
#import <CoreData/CoreData.h> 
@interface SampleEntity : NSManagedObject 
@property (nonatomic, retain) UIColor *color; 
@end 

@interface ColorToDataTransformer : NSValueTransformer 
@end 

//SampleEntity.m

#import "SampleEntity.h" 

@implementation SampleEntity 

@dynamic color; 

@end 

@implementation ColorToDataTransformer 

+ (BOOL)allowsReverseTransformation { 
    return YES; 
} 

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


- (id)transformedValue:(id)value { 
    UIColor *color = (UIColor *)value; 
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:color]; 
    return data; 
} 

- (id)reverseTransformedValue:(id)value { 
    NSData *data = (NSData *)value; 
    UIColor *color = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 
    return color; 
} 

@end