【问题标题】:Save and Retrieve of an UIImage on CoreData在 CoreData 上保存和检索 UIImage
【发布时间】:2011-03-22 03:46:25
【问题描述】:

在我的应用程序中,我试图在核心数据中保存和检索图像。在将 UIimage 约定为 NSData 之后,我能够成功保存图像,但是当我尝试将图像作为 NSData 获取时,它会显示如下所示的输出,

案例 1:尝试从 DB 中显示为字符串时。

 <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

我花了很多时间在这上面。请帮帮我!

【问题讨论】:

  • 请添加有关如何将图像放入 NSData 以及如何检索它的代码。晦涩的错误消息没有多大帮助
  • @IWasRobbed 谢谢你的回复,我把它写成了我的代码。请找出我做错了什么。

标签: iphone objective-c core-data uiimage save


【解决方案1】:

不确定您是否已经解决了这个问题,但我可以在 Core Data 中保存/检索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];

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

【讨论】:

  • 我喜欢示例代码。但是,很高兴提及 yourUIImage 的类型为 UIImage *
【解决方案2】:

这是一个非常有效的正确解决方案。

1) 使用 Core Data 存储 UIImage:

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

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

2) 从 Core Data 中检索 UIImage:

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

这就是它的全部内容,效果很好。

【讨论】:

  • 抱歉,没看到 Brian 已经回答了几乎完全相同的解决方案。
  • 无需将 UIImagePNGRepresentation 传递给 NSData 初始化程序,因为它已经返回了一个 NSData 对象。
【解决方案3】:

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

dataBytes = [array objectAtIndex:0];

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

您应该将代码调整为:

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

这样,您从数组中取出第一个 Event 对象,然后获取其 imgPng 属性(NSData 的一个实例,这正是您想要的)。

附带说明一下,您在上面一行中使用alloc-init 声明dataBytes 可能是多余的,因为您随后立即将dataBytes 更改为来自您的事件的数据。

【讨论】:

  • exact 相同的错误?您可以编辑上面的问题并将更新后的错误复制/粘贴到其中吗?谢谢。
  • @Sivanathan - 请注意,这是一个略有不同的错误:这一次,Event 对象正在获取无法识别的选择器data,而不是length。至少这意味着我们走在正确的轨道上。您可以发布您的 Event 类的代码(它应该由 Core Data 生成)或您的 Core Data 模型的屏幕截图吗?具体来说,我正在寻找 Event 的 data 属性的 getter 名称。
  • @Tim - 我附上了我的数据模型屏幕截图,如果我做错了,请指出我
  • @Sivanathan - 好吧,这是我的错误。使用模型中的 imgPng 属性,而不是 data 属性。 (我被 NSData 上的所有数据访问者所接受,并没有考虑在您的第一个代码块中查看您的 setValue:forKey: 调用。)我已经编辑了我的答案以反映这一点。
  • @Tim 我真的很感谢你。我已经更改了 imgPng 并且它工作正常
【解决方案4】:

我使用的解决方案是创建下面的类别。您只需要在项目中使用它即可。使用这个存储图像就像你存储 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

【讨论】:

  • 是的,这是最简单的方法,因为如果一个类符合 NSCoding 协议,那么可以使用 NSKeyedUnarchiveFromDataTransformerName(核心数据的标准)。
  • 我很困惑。没有使用 NSKeyedUnarchiveFromDataTransformerName。
  • 其实 UIImage 已经符合 NSCoding,不需要添加任何代码。所以它可以用作Transformable 属性。见Store UIImage in CoreData Without Writing Any Code
【解决方案5】:

此示例代码具有如何在 Core Data 中存储 UIImage 的示例: https://developer.apple.com/library/ios/#samplecode/PhotoLocations/Introduction/Intro.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    相关资源
    最近更新 更多