Проблема с трансформируемыми атрибутами основных данных для изображений - PullRequest
1 голос
/ 21 февраля 2012

Я застрял на том, что должно быть очень простым делом: иметь Core Data Entity для хранения / отображения (с помощью привязок) изображения, назначенного в качестве преобразуемого атрибута.

Я прочитал много похожих постов в стеке (например, см. здесь и здесь ), но у меня все еще проблемы с этим после разработки примера кодаи исследовал другие статьи (например, см. здесь , а также здесь ).Это связано с моим ранним вопросом , который я до сих пор не решил.

Я создал простое основанное на doc приложение Core Data, чтобы продемонстрировать проблему.Управляемый объект Core Data называется «TheEntity», а атрибут «theImageAtt».Сущность, как определено в Базовых данных, показана ниже (ImageValueTransformer - NSValueTransformer):
enter image description here

Я позволил XCode генерировать заголовок подкласса NSManagedObject и файлы реализации (я пропустил код для «имени»"атрибут, чтобы сделать его проще):

//  TheEntity.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import "ImageValueTransformer.h"
@interface TheEntity : NSManagedObject
@property (nonatomic, retain) NSImage * theImageAtt;
@end
-----------------------
//  TheEntity.m
#import "TheEntity.h"
@implementation TheEntity
@dynamic theImageAtt;
@end

Ниже приведены файлы заголовка и реализации для моего" ImageValueTransformer. "Множество примеров этого в стеке и в других местах (tiff является произвольным).

//  ImageValueTransformer.h
#import <Foundation/Foundation.h>
@interface ImageValueTransformer : NSValueTransformer
@end
-------------------------------
//  ImageValueTransformer.m
#import "ImageValueTransformer.h"
@implementation ImageValueTransformer
+ (BOOL)allowsReverseTransformation {return YES;}
+ (Class)transformedValueClass {
    return [NSData class];  // have also tried: return [NSImage class]; 
}
- (id)transformedValue:(id)value {    
    NSData *data = [value TIFFRepresentation]; 
    return data;
}
- (id)reverseTransformedValue:(id)value {
    NSImage *imageRep = [[NSImage alloc] initWithData:value];
    return imageRep;
}
@end

Преобразователь значения можно инициализировать / зарегистрировать, выделив его экземпляр в MyDocument.m, но в конце, это не имеет большого значения, если заголовок преобразователя импортируется в заголовок объекта (см. выше).Я экспериментировал с этим, и это не устраняет ошибку, которую я получаю ниже.Для справки: ранее обсуждалось, нужно ли преобразовать значение для регистрации (см. Комментарии CornPuff и Brian Webster).

Возвращаясь к рассматриваемой проблеме, хорошим примером кода от Apple является здесь , который показывает альтернативную инициализацию преобразователя значения, я тоже пробовал эту настройку.

Установкаэто в действие, у меня есть метод, чтобы загрузить тестовое изображение и назначить его для трансформируемого атрибута в MyDocument.m (из выбранного экземпляра Entity в NSTable):

- (IBAction)addImg:(id)sender {
    NSImage *theImg = [[NSImage alloc] initWithContentsOfFile:@"/Desktop/testImage.jpg"];
    //[theImageView setImage:theImg]; // as a test, this displays ok
    // "theEntities" below are defined as an IBOutlet to my Array Controller:
    [theEntities setValue:theImg forKeyPath:@"selection.theImageAtt"];
    NSLog(@"after setting the image ..."); // this never logs
}

Обнуление, гдеразрывы кода, строка ниже:

[theEntities setValue:theImg forKeyPath:@"selection.theImageAtt"];

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

Cannot create BOOL from object <4d4d002a 0003717e 8989898a 8a8a8b8b 8b8b8b8b
8a8a8a89 89898888 88878787 8a8a8a89 89898888 88888888 88888889 89898a8a
8a8a8a8a 8b8b8b88 88888787 87898989 8a8a8a89 89898a8a 8a8c8c8c 8b8b8b8a
8a8a8888 .... and so on for the size of the Image array ...

Если я закомментирую вышеупомянутую строку, то мой NSTable заполняется очень хорошо (поэтому привязки и контроллер массивакажется нормальным), но, конечно, без изображения в NSImageView.

В качестве проверки, код преобразования, используемый в преобразователе изображений, работает должным образом (это проверяется отдельно от преобразователя значения):

// Image to Data Conversion:
NSImage *imageIn = [[NSImage alloc] initWithContentsOfFile:@"testImage.jpg"];
NSData *imgData = [imageIn TIFFRepresentation];
NSImage *imageOut = [[NSImage alloc] initWithData:imgData];
[theImageDisplay setImage:imageOut]; 

Что мне не хватает в этом?

1 Ответ

0 голосов
/ 24 февраля 2012

Я обнаружил, что ошибка, указанная выше, а именно,

Cannot create BOOL from object ...

не возникает при использовании ячейки изображения или ячейки изображения (подклассы NSImageView), а не пользовательского представления, в которое я пытался записать ранее.

Итак, сейчас я использую преобразователь значений по умолчанию, а не преобразователь пользовательских значений. Это работоспособное решение, но с академической точки зрения было бы неплохо узнать, почему настраиваемое представление по умолчанию приводило к ошибкам при привязке к атрибуту базовых данных (определяемому как преобразуемое в модели базовой даты).

Если немного углубиться в это, Image Well наследуется от NSImageView, поэтому, по крайней мере, одно отличие состоит в том, что они различаются в отношении свойства "editable" (Image Wells являются редактируемыми, что хорошо работает с Drag-n-Drop) , Поэтому, пытаясь согласовать эти два параметра, я настроил свой пользовательский вид на редактируемый, думая, что это может решить проблему:

theImageView = [[NSImageView alloc] init];
[theImageView setEditable:YES];

Но это должно быть что-то еще, это не устраняет ошибку выше. По крайней мере, сейчас у меня есть работоспособное решение. Если другие столкнутся с этим, я надеюсь, что эти заметки будут полезны!

...