2010-07-28 49 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