0 sqlite core-data picker uiimageview ios
我正在尝试将图像保存在核心数据中但是在我在模拟器中选择后,它不会显示在图像视图中?以下是代码示例:
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (fugitive_.image != nil) {
self.fugitiveImage.image = [UIImage imageWithData:fugitive_.image];
}
}
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
fugitive.image = UIImagePNGRepresentation([info objectForKey:UIImagePickerControllerEditedImage]);
[self dismissModalViewControllerAnimated:YES];
[picker release];
}
Run Code Online (Sandbox Code Playgroud)
首先,不要在Core Data中存储图像(或任何二进制数据); 特别是在iOS上.您将获得更好的性能,将其存储在磁盘上,然后在Core Data中存储对文件位置的引用.
其次,您的示例代码未显示您如何将数据放入 Core Data.因此很难提出解决方案.
我没有找到如何做到这一点的简单参考,所以这里有一个:
要在iOS 5.0之前的环境中在磁盘上设置图像缓存,您需要首先在您的实体上创建一个属性a NSString.在这个例子中,我们将命名该属性imageFilename.一旦完成,我们将要NSManagedObject为我们的实体创建一个子类,以便我们可以实现辅助方法:
@interface MyEntity : NSManagedObject
@property (nonatomic, retain) NSString *imageFilename;
@property (nonatomic, retain) NSImage *image;
@end
Run Code Online (Sandbox Code Playgroud)
我们将让Core Data管理imageFilename它,因为它是在模型中定义的.但是,我们将实现访问器image.
@implementation MyEntity
@dynamic imageFilename;
@synthesize image = _image;
- (void)setImage:(UIImage*)image
{
NSString *filename = [self imageFilename];
if (!filename) {
filename = [[NSProcessInfo processInfo] globallyUniqueString];
[self setImageFilename:filename];
}
[_image release];
_image = [image retain];
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [cachePath stringByAppendingPathComponent:filename];
NSData *data = UIImagePNGRepresentation(image);
NSError *error = nil;
if (![data writeToFile:filePath options:NSDataWritingAtomic error:&error]) {
NSLog(@"Failed to write image to disk: %@\n%@", [error localizedDescription], [error userInfo]);
return;
}
}
Run Code Online (Sandbox Code Playgroud)
在-setImage:将图像保存到磁盘到缓存目录(注意,缓存目录没有备份,并且可以通过系统中的低空间状况的事件中删除).如果尚未创建一个随机文件名,它会选择一个随机文件名.
故意不存储路径,因为应用程序沙箱的目录可以更改.因此,我们只想将文件名存储在Core Data中并解析路径.
我们还在内存中保留了对图像的引用,这样如果在此实体的生命周期中再次询问图像,我们就不会访问磁盘.这就是@synthesize我们实现访问器的原因.
请注意,我们将图像作为PNG存储在磁盘上.这可能很昂贵(压缩程序相对较慢),但它使图像保持通用格式,这可能很有用.
- (UIImage*)image
{
if (_image) return _image;
NSString *filename = [self imageFilename];
if (!filename) return nil;
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [cachePath stringByAppendingPathComponent:filename];
if (![[NSFileManager defaultFileManager] fileExistsAtPath:filePath]) return nil;
_image = [[UIImage alloc] initWithContentsOfFile:filePath];
return _image;
}
Run Code Online (Sandbox Code Playgroud)
实现这-image几乎是相反的.我们检查一下我们是否有文件名; 解析完整路径并将图像加载到内存中,然后将其返回给调用者.
- (void)prepareForDeletion
{
[super prepareForDeletion];
NSString *filename = [self imageFilename];
if (!filename) return nil;
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [cachePath stringByAppendingPathComponent:filename];
NSError *error = nil;
if (![[NSFileManager defaultFileManager] removeItemAtPath:filePath error:&error]) {
NSLog(@"Potential error removing on disk image: %@\n%@", [error localizedDescription], [error userInfo]);
}
}
Run Code Online (Sandbox Code Playgroud)
我们希望尽可能保持缓存目录的清洁,这样我们就不会创建低空间情况.因此,当要从Core Data中删除实体时,我们要从磁盘中删除该文件.删除期间发生的实际错误对我们来说是一个非致命的问题.这可能是一个错误,因为该文件已被删除或其他内容.没有理由为此错误完全失败,但记录它很重要.
- (void)willTurnIntoFault
{
[super willTurnIntoFault];
[_image release], _image = nil;
}
@end
Run Code Online (Sandbox Code Playgroud)
最后,我们实现了该-willTurnIntoFault方法,以便我们可以在该实体生命周期结束时释放对映像的内存引用.