2010-07-28 72 views
17

在我的应用程序中,我试图保存和检索核心数据中的图像。我可以在将UIimage约定为NSData后成功保存图像,但是当我试图以NSData形式获取图像时,它会显示如下输出,在CoreData上保存并检索UIImage

情况1:尝试从数据库显示为字符串时。

<Event: 0x5b5d610> (entity: Event; id: 0x5b5ce30 <x-coredata://F51BBF1D-6484-4EB6-8583-147E23D9FF7B/Event/p1> ; data: <fault>) 

案例2:当试图显示为数据

[Event length]: unrecognized selector sent to instance 0x5b3a9c0 
2010-07-28 19:11:59.610 IMG_REF[10787:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Event length]: unrecognized selector sent to instance 0x5b3a9c0' 

我的代码,

to save: 

NSManagedObjectContext *context = [self managedObjectContext]; 

newsObj = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:context]; 

NSURL *url = [NSURL URLWithString:@"http://www.cimgf.com/images/photo.PNG"]; 

NSData *data = [[NSData alloc] initWithContentsOfURL:url]; 

uiImage = [UIImage imageWithData:data]; 

NSData * imageData = UIImagePNGRepresentation(uiImage); 

[newsObj setValue:imageData forKey:@"imgPng"]; 

NSError *error; 

@try{ 

    if (managedObjectContext != nil) { 

     if (![managedObjectContext save:&error]) { 

      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 

      NSString * infoString = [NSString stringWithFormat:@"Please check your connection and try again."]; 

      UIAlertView * infoAlert = [[UIAlertView alloc] initWithTitle:@"Database Connection Error" message:infoString delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; 

      [infoAlert show]; 

      [infoAlert release]; 
     } 
    } 

}@catch (NSException *exception) { 

    NSLog(@"inside exception"); 
} 

检索,

NSManagedObjectContext *context = [self managedObjectContext]; 

    NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init]; 

    NSEntityDescription *entity1 = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:context]; 

    [fetchRequest setEntity:entity1]; 

    NSError *error; 

    NSArray * array = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

    if (array == nil) { 

     NSLog(@"Testing: No results found"); 

    }else { 

     NSLog(@"Testing: %d Results found.", [array count]); 
    } 

    NSData * dataBytes = [[array objectAtIndex:0] data]; 

    image = [UIImage imageWithData:dataBytes]; 

    [fetchRequest release]; 


} 

@catch (NSException *exception) { 

    NSLog(@"inside exception"); 
} 

Error: 
    Testing: 3 Results found. 
    2010-07-28 23:27:51.343 IMG_REF[11657:207] -[Event data]: unrecognized selector sent  to instance 0x5e22ce0 
    2010-07-28 23:27:51.344 IMG_REF[11657:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Event data]: unrecognized selector sent to instance 0x5e22ce0' 
    *** Call stack at first throw: 
    (
0 CoreFoundation      0x02566919 __exceptionPreprocess + 185 
1 libobjc.A.dylib      0x026b45de objc_exception_throw + 47 
2 CoreFoundation      0x0256842b -[NSObject(NSObject) doesNotRecognizeSelector:] + 187 
3 CoreFoundation      0x024d8116 ___forwarding___ + 966 
4 CoreFoundation      0x024d7cd2 _CF_forwarding_prep_0 + 50 
5 IMG_REF        0x00003b06 -[IMG_REFViewController showAction] + 353 
6 UIKit        0x002bae14 -[UIApplication sendAction:to:from:forEvent:] + 119 
7 UIKit        0x004c214b -[UIBarButtonItem(UIInternal) _sendAction:withEvent:] + 156 
8 UIKit        0x002bae14 -[UIApplication sendAction:to:from:forEvent:] + 119 
9 UIKit        0x003446c8 -[UIControl sendAction:to:forEvent:] + 67 
10 UIKit        0x00346b4a -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527 
11 UIKit        0x003456f7 -[UIControl touchesEnded:withEvent:] + 458 
12 UIKit        0x002de2ff -[UIWindow _sendTouchesForEvent:] + 567 
13 UIKit        0x002c01ec -[UIApplication sendEvent:] + 447 
14 UIKit        0x002c4ac4 _UIApplicationHandleEvent + 7495 
15 GraphicsServices     0x02dccafa PurpleEventCallback + 1578 
16 CoreFoundation      0x02547dc4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52 
17 CoreFoundation      0x024a8737 __CFRunLoopDoSource1 + 215 
18 CoreFoundation      0x024a59c3 __CFRunLoopRun + 979 
19 CoreFoundation      0x024a5280 CFRunLoopRunSpecific + 208 
20 CoreFoundation      0x024a51a1 CFRunLoopRunInMode + 97 
21 GraphicsServices     0x02dcb2c8 GSEventRunModal + 217 
22 GraphicsServices     0x02dcb38d GSEventRun + 115 
23 UIKit        0x002c8b58 UIApplicationMain + 1160 
24 IMG_REF        0x00002aac main + 102 
25 IMG_REF        0x00002a3d start + 53 
) 
terminate called after throwing an instance of 'NSException' 

注:以上错误是何时到来要执行NSData * dataBytes = [[array objectAtIndex:0] data];线。 Data Model http://www.freeimagehosting.net/uploads/7c286931cc.png

我花了很多时间与此。请帮助我!

+0

请添加有关如何将图像放入NSData以及如何检索它的代码。晦涩的错误消息没有多大帮助 – iwasrobbed 2010-07-28 13:20:49

+0

@IWasRobbed感谢您的回复,我将其放入我的代码中。请找出我做了什么错误。 – Sivanathan 2010-07-28 13:47:54

回答

7

当您检索图像时,您正在执行提取请求并将结果存储在变量array中,这意味着array包含一个NSArray事件对象。然后,以后,你分配:

dataBytes = [array objectAtIndex:0];

这意味着dataBytes,您声明为NSData的,现在实际上事件的一个实例。然后,当你去初始化图像时,imageWithData:的一部分实现调用length它预期是你的NSData对象,但实际上是一个Event对象,因此是错误消息。

你应该调整你的代码如下:

dataBytes = [[array objectAtIndex:0] imgPng];

这样的话,你得到的第一个活动对象从数组中,然后获取其imgPng财产(NSData的实例,这就是你想)。

作为一个侧面说明,您使用allocdataBytes声明 - init就行了上述可能是多余的,因为你改变dataBytes是从事件的数据随即。

+0

@Tim我改变了你说的,但仍显示相同的错误。 – Sivanathan 2010-07-28 14:26:49

+0

*确切*相同的错误?你可以编辑上面的问题,并将更新后的错误复制/粘贴到它?谢谢。 – Tim 2010-07-28 17:35:24

+0

@Tim ya我确定我会粘贴并感谢您的回复 – Sivanathan 2010-07-28 17:51:56

39

不知道如果你已经得到这个理顺,但我很能保存/恢复UIImage对象在核心数据如下:

为了节省:

NSData *imageData = UIImagePNGRepresentation(yourUIImage); 
[newManagedObject setValue:imageData forKey:@"image"]; 

并加载:

NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath]; 
UIImage *image = [UIImage imageWithData:[selectedObject valueForKey:@"image"]]; 
[[newCustomer yourImageView] setImage:image]; 

希望这会有所帮助。我在核心数据上使用UITableView,并在我的tableView:didSelectRowAtIndexPath:方法中从数据库中提取图像。

+1

我喜欢示例代码。不过,提及您的UIImage是UIImage类型* – 2012-10-08 08:11:07

26

下面是适当的解决方案,工作得很好。

1)中存储的UIImage核心数据:

NSData* coreDataImage = [NSData dataWithData:UIImagePNGRepresentation(delegate.dancePhoto)]; 

确保 “coreDataImage” 是NSData类型。您必须在模型中为“coreDataImage”设置类型为“二进制数据”。

2)检索的UIImage从核心数据:

UIImage* image = [UIImage imageWithData:selectedDance.danceImage]; 

这是所有有它,伟大工程。

+1

会很高兴。对不起,没有看到Brian已经用几乎完全相同的解决方案回答了。 – Detra83 2011-02-02 22:22:22

+1

不需要将UIImagePNGRepresentation传递给NSData初始值设定项,因为它已经返回一个NSData对象。 – Gargoyle 2014-01-17 18:54:21

7

我使用的解决方案是创建类别波纹管。你只需要它在你的项目中工作。使用这种存储图像的作品就像你在哪里存储一个NSData

的UIImage + NSCoding.h

@interface UIImage (UIImage_NSCoding) <NSCoding> 
- (void)encodeWithCoder:(NSCoder *)aCoder; 
- (id)initWithCoder:(NSCoder *)aDecoder; 
@end 

的UIImage + NSCoding.m

#import "UIImage+NSCoding.h" 

@implementation UIImage (UIImage_NSCoding) 

- (void)encodeWithCoder:(NSCoder *)aCoder 
{ 
    NSData *imageData = UIImagePNGRepresentation(self); 
    [aCoder encodeDataObject:imageData]; 
} 

- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
    [self autorelease]; 
    NSData* imageData = [aDecoder decodeDataObject]; 
    self = [[UIImage alloc] initWithData:imageData]; 
    return self; 
} 
@end 
+0

是的,这是最简单的方法,因为如果一个类符合NSCoding协议,那么可以使用NSKeyedUnarchiveFromDataTransformerName(核心数据的标准)。 – CarlJ 2012-04-16 18:52:59

+0

我很困惑。没有使用NSKeyedUnarchiveFromDataTransformerName。 – 2012-10-08 08:12:55

+0

实际上UIImage已经符合NSCoding而不需要添加任何代码。所以它可以用作'Transformable'属性。请参阅[不使用任何代码在CoreData中存储UIImage](http://ootips.org/yonat/uiimage-in-coredata/) – Yonat 2015-01-12 04:29:05