1

私は非常に簡単なことであると思われることに固執しています。コアデータエンティティに、変換可能な属性として割り当てられた画像を(バインディングを介して)保存/表示させます。

スタック上の多くの関連する投稿を読みましたが(たとえば、こことここを参照)、サンプルコードを開発し、他の記事を調査した後(たとえば、ここここ参照)、まだ問題があります。これは私の以前の質問に関連していますが、まだ解決していません。

問題を実証するために、簡単なドキュメントベースのCoreDataAppを作成しました。CoreData管理対象オブジェクトは「TheEntity」および属性「theImageAtt」と呼ばれます。Core Dataで定義されているエンティティを以下に示します(ImageValueTransformerはNSValueTransformerです)。
ここに画像の説明を入力してください

XCodeにNSManagedObjectサブクラスヘッダーと実装ファイルを生成させます(簡単にするために「name」属性のコードを省略しました)。

//  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の変換可能な属性に割り当てるメソッドがあります(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 Transformerで使用される変換コードは期待どおりに機能します(これは値トランスフォーマーとは別にテストされます)。

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

私はこれに何が欠けていますか?

4

1 に答える 1

0

上記で報告されたエラー、つまり、

Cannot create BOOL from object ...

以前に書き込もうとしていたカスタム ビューではなく、イメージ ウェルまたはイメージ セル (NSImageView のサブクラス) を使用している場合は発生しません。

したがって、今のところ、カスタム値トランスフォーマーではなく、デフォルト値トランスフォーマーを使用しています。これは実行可能な解決策ですが、学術的に言えば、既定のカスタム ビューが Core Data 属性 (Core Date Model で変換可能として定義されている) にバインドするときにエラーを引き起こした理由を知っておくとよいでしょう。

これをもう少し掘り下げると、Image Well は NSImageView を継承しているため、少なくとも 1 つの違いは、「編集可能」プロパティに関して異なることです (Image Well は編集可能で、ドラッグ アンド ドロップでうまく機能します)。したがって、これら 2 つを調整するために、カスタム ビューを編集可能に設定し、これで問題が解決する可能性があると考えました。

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

しかし、それは別のものでなければなりません。これは上記のエラーを解決しません。少なくとも今のところ、実行可能な解決策があります。他の人がこれに遭遇した場合、これらのメモが役立つことを願っています!

于 2012-02-24T04:25:56.657 に答える