2014-10-27 2 views
1

В модели данных я определил цвет как преобразуемый атрибут и назначил ему ColorTransformer. Он работает, с помощью одного и того же трансформатора я могу привязать его к ColorPicker, сохранить и открыть документ. Screenshot from data model Но когда я пытаюсь получить доступ к нему из кода:Почему мой класс NSColor NSConcreteData?

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 

Изменение геттер и сеттер не помогает:

- (NSColor *)color { 

    [self willAccessValueForKey:@"color"]; 
    NSData *colorData = [self primitiveValueForKey:@"color"]; 
    [self didAccessValueForKey:@"color"]; 
    if (colorData == nil) { 
     return nil; 
    } 


    NSColor * color = [NSKeyedUnarchiver unarchiveObjectWithData:colorData]; 
    return color; 
    } 

- (void)setColor:(NSColor *)color { 
    NSLog(@" -------------- > Setting color %@", color); 
    NSData * theData=[NSArchiver archivedDataWithRootObject:color]; 
    [self willChangeValueForKey:@"color"]; 
    [self setPrimitiveValue:theData forKey:@"color"]; 
    [self didChangeValueForKey:@"color"]; 
} 

Это вызывает ошибку:

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

Как получить цвет NSColor?

+0

Является ли это подклассом «NSValueTransformer», о котором мы говорим здесь? Если это так, то вы не используете его из кода. – trojanfoe

+0

BMColorTransformer является подклассом NSTransformer. Но, может быть, есть правильный вопрос: как использовать подкласс NSTransformer в коде? –

+0

NSValueTransformer конечно –

ответ

1

Вот NSString < ->NSColor трансформатор я написал некоторое время назад, который предназначен для хранения цветов с использованием значений RGB в NSUserDefaults, как я не хотел использовать по умолчанию NSData объектов:

StringColourTransformer.h :

@interface StringColourTransformer : NSValueTransformer 

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

@end 

StringColourTransformer.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 (это называется от одноточечного где _stringColourTransformer является переменным экземпляром):

_stringColourTransformer = [[StringColourTransformer alloc] init]; 
[NSValueTransformer setValueTransformer:_stringColourTransformer 
           forName:@"StringColourTransformer"]; 

и преобразование так просто, как:

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

Примечание: глядя на код, сейчас я бы, вероятно, использовать [NSValueTranformer valueTransformerForName:] методов в toString/fromString, а не создавать новый экземпляр каждый раз. Это, наверное, дешевле.

1

Если у вас есть вопрос о том, как хранить объект UIColor (или NSColor on OS X) в Core Data ...: NSValueTransformer не требуется. Вышеуказанное «Имя» в основном модельере данных данных должно быть пустым (теперь есть: «BMColorTransformer»).

данность ("MyData") интерфейс (используйте NSColor соответственно с OS X), то выглядит так в коде:

@interface MyData : NSManagedObject 

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

@end 

и реализации ...

@implementation MyData 

// other attributes ... 
@dynamic color; 

@end 

Но если вы не Не хотите, чтобы UIColor (или NSColor) хранился как NSData, что приводит к BLOB-формату в базе данных Sqlite - вам нужно написать NSValueTransformer, как и тот, который был отправлен @trojanfoe. Он говорит: «Мне не нравилось использование NSData по умолчанию» - я думаю, он предпочитает читаемый формат, а не бинарный формат (??).

+0

Так просто. BTW. У моего BTColorTransformer был - (NSColor *) ... вместо + (Цвет *) ... Теперь работает! –

Смежные вопросы