Tengo una aplicación Core Data con un modelo de datos bastante simple. Quiero poder almacenar instancias de NSImage en la tienda persistente como objetos PNG Bitmap NSData, para ahorrar espacio.¿Por qué mi atributo de datos centrales transformable no utiliza mi NSValueTransformer personalizado?
Para este fin, escribí un NSValueTransformer simple para convertir un NSImage a NSData en formato de mapa de bits PNG. Estoy registrando el transformador valor con este código en mi aplicación delegado:
+ (void)initialize
{
[NSValueTransformer setValueTransformer:[[PNGDataValueTransformer alloc] init] forName:@"PNGDataValueTransformer"];
}
En mi modelo de datos, he puesto el atributo de imagen para ser transformable, y se especifica PNGDataValueTransformer
como nombre del valor transformador.
Sin embargo, mi transformador de valor personalizado no se está utilizando. Lo sé porque he colocado mensajes de registro en los métodos de -transformedValue:
y -reverseTransformedValue
de mi transformador de valor que no se registran, y los datos que se guardan en el disco son solo un NSI archivado, no el PNG NSData objeto que debería ser.
¿Por qué no funciona?
Aquí está el código de mi valor transformador:
@implementation PNGDataValueTransformer
+ (Class)transformedValueClass
{
return [NSImage class];
}
+ (BOOL)allowsReverseTransformation
{
return YES;
}
- (id)transformedValue:(id)value
{
if (value == nil) return nil;
if(NSIsControllerMarker(value))
return value;
//check if the value is NSData
if(![value isKindOfClass:[NSData class]])
{
[NSException raise:NSInternalInconsistencyException format:@"Value (%@) is not an NSData instance", [value class]];
}
return [[[NSImage alloc] initWithData:value] autorelease];
}
- (id)reverseTransformedValue:(id)value;
{
if (value == nil) return nil;
if(NSIsControllerMarker(value))
return value;
//check if the value is an NSImage
if(![value isKindOfClass:[NSImage class]])
{
[NSException raise:NSInternalInconsistencyException format:@"Value (%@) is not an NSImage instance", [value class]];
}
// convert the NSImage into a raster representation.
NSBitmapImageRep* bitmap = [NSBitmapImageRep imageRepWithData: [(NSImage*) value TIFFRepresentation]];
// convert the bitmap raster representation into a PNG data stream
NSDictionary* pngProperties = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:NSImageInterlaced];
// return the png encoded data
NSData* pngData = [bitmap representationUsingType:NSPNGFileType properties:pngProperties];
return pngData;
}
@end
Hola Brian, el '+ initialize' método es en mi aplicación delegado, no el transformador de valor y que sin duda puede verificar que está siendo llamado. Si pongo un punto de interrupción en el método '-init' de mi NSValueTransformer, definitivamente se inicializa. Si configuro el atributo para que sea del tipo "binario" y aplique mi transformador de valor a cada enlace en IB, funciona bien. Simplemente no entiendo por qué el transformador personalizado no se está utilizando cuando especifico el tipo de atributo como Transformable. –