2010-02-21 182 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