我被困在应该做的非常简单的事情上:拥有一个Core Data Entity存储/显示(通过绑定)一个被指定为可转换属性的图像。
我已经在堆栈上阅读了很多相关帖子(例如,请参阅here和here),但在开发示例代码并研究其他文章后(例如, see here以及here)。这与我之前的question有关,我还没有解决。
我创建了一个简单的基于doc的Core Data App来演示这个问题。 Core Data托管对象称为“TheEntity”,属性为“theImageAtt”。核心数据中定义的实体如下所示(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”的标题和实现文件。很多关于Stack和其他地方的例子(tiff rep是任意的)。
// 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中分配它的实例来初始化/注册Value Transformer,但最后,只要将变换器头导入到theEntity Header中就没那么重要了(见上文) 。我已经尝试过这个并没有消除我得到的错误。作为参考,需要注册值变换器earlier discussion on whether or not(参见CornPuff和Brian Webster的评论)。
回到手头的问题,Apple的一个很好的代码示例是here,它显示了值变换器的替代初始化,我也试过了这个设置。
实现这一点,我有一种方法来加载测试图像并将其分配给MyDocument.m中的可转换属性(来自NSTable中选定的Entity实例):
- (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];
我对此缺少什么?
答案 0 :(得分:0)
我发现上面报告的错误,即
Cannot create BOOL from object ...
使用Image Well或Image Cell(NSImageView的子类)而不是我之前尝试写入的自定义视图时,不会发生。
所以现在我使用默认值转换器而不是自定义值转换器。这是一个可行的解决方案,但从学术上讲,很高兴知道为什么默认的自定义视图在绑定到Core Data属性时会导致错误(在Core Date Model中定义为可转换)。
进一步深入研究,Image Well继承自NSImageView,因此至少有一个不同之处在于它们在“可编辑”属性方面是截然不同的(Image Wells是可编辑的,与Drag-n-Drop兼容) 。因此,为了协调这两者,我将自定义视图设置为可编辑,认为这可以解决问题:
theImageView = [[NSImageView alloc] init];
[theImageView setEditable:YES];
但它必须是别的东西,这不能解决上面的错误。至少现在,我有一个可行的解决方案。如果其他人遇到这个,我希望这些笔记有用!