2010-07-28 2 views
17

В моем приложении я пытаюсь сохранить и получить изображение в основных данных. Я могу сохранить изображение успешно после соглашения UIimage в NSData, но когда я пытаюсь получить изображение как NSData, он показывает результат, как указано ниже,Сохранение и получение UIImage на CoreData

case 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

+0

@IWasRobbed благодарит ваш ответ, и я поместил его в свой код. узнайте, что я сделал. – Sivanathan

ответ

7

Когда вы извлекаете изображение, вы выполняете запрос на выборку и сохраняете результаты в переменной array, то есть array содержит объекты NSArray объектов Event. Потом, позже, вы назначаете:

dataBytes = [array objectAtIndex:0];

Это означает, что dataBytes, который вы объявили в NSData, теперь на самом деле является экземпляром Event. Затем, когда вы идете инициализировать изображение, часть реализации imageWithData: вызывает length на том, что он ожидает быть вашим объектом NSData, но на самом деле является объектом Event, поэтому сообщение об ошибке.

Вы должны настроить свой код следующим образом:

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

Таким образом, вы получаете первый объект Event из массива, то извлечение его свойства imgPng (экземпляр NSData, который является то, что вы хотеть).

Как примечание стороны, ваша декларация dataBytes с помощью alloc - init на линии выше, может быть посторонним, так как вы измените dataBytes быть данными с вашего события сразу же после этого.

+0

@Tim Я изменил, как вы сказали, но все же показывает ту же ошибку. – Sivanathan

+0

* Точная * такая же ошибка? Вы можете изменить свой вопрос выше и скопировать/вставить ошибку после обновления в нее? Благодарю. – Tim

+0

@ Наверное, я вставлю и спасибо вашему ответу – Sivanathan

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

Мне нравятся образцы кодов. Тем не менее, было бы неплохо упомянуть, что yourUIImage имеет тип UIImage * –

26

Вот правильное решение, которое работает очень хорошо.

1) Запоминание UIImage с Core Data:

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

Убедитесь, что "coreDataImage" имеет тип NSData. Вы должны установить тип «Двоичные данные» для «coreDataImage» в своей модели.

2) Получение UIImage из основных данных:

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

Это все есть на него, прекрасно работает.

+1

Извините, не видел, что Брайан уже ответил почти с тем же самым решением. – Detra83

+1

Не нужно передавать UIImagePNGRпредставление в инициализатор NSData, поскольку он уже возвращает объект NSData. – Gargoyle

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

+0

Я смущен. Нигде не используется NSKeyedUnarchiveFromDataTransformerName. –

+0

Фактически UIImage уже соответствует NSCoding без необходимости добавлять код. Поэтому он может использоваться как атрибут «Transformable». см. [Сохранить UIImage в CoreData без написания кода] (http://ootips.org/yonat/uiimage-in-coredata/) – Yonat

Смежные вопросы