在“多对多关系”环境中将图片保存在 Core Data 中

Posted

技术标签:

【中文标题】在“多对多关系”环境中将图片保存在 Core Data 中【英文标题】:saving pictures in Core Data in 'to-many relationship' environment 【发布时间】:2010-11-24 11:24:05 【问题描述】:

我正在处理我的小项目,该项目使用 Core Data 拍摄并保存照片,非常简单。我有两个实体;一个是“人”,另一个是“图像”。从 Person 到 Image 的关系是对多的,从 Image 到 Person 我也有反向关系。

目前我只需要将多个图像(从 iPhone 相机拍摄或从库中选择)添加到一个 Person 实体

我想知道是否有任何示例代码可以使用 Core Data 处理与 UIImage 的多对多关系。

非常感谢。

======================

其实我希望我能具体说明问题。我正在尝试做的是使用在多对关系中免费提供的访问方法来添加对象,例如

- (void)addPersonImageObject:(PersonImage *)value;

我还实现了与 ImageToDataTransformer 相关的方法。

我在这件事上花了将近一周的时间,我想我需要一个指导示例代码,我可以先研究它以用于我的 add 项目。

【问题讨论】:

我不确定问题是什么。您在将 UIImage 对象编码为 NSData 对象时遇到问题吗?或者您在创建从 Parent 到 Image 的多对多关系时遇到问题?概括地说,这是两个不相关的问题。另外,您是否继承了 NSManagedObject 并创建了 Parent 和 Image 类? 【参考方案1】:

除了将UIImage 转换为NSData 并返回之外,与UIImages 建立一对多关系并没有什么特别之处。因此,任何包含一对多关系的核心数据教程都应该足够了。如果您需要示例代码,可以查看 Apple 的 iPhoneCoreDataRecipes。

一些可帮助您入门的提示。假设我们有一个 PersonViewController,它继承自一个 `UITableViewController',它被调用如下:

PersonViewController *personViewController = [[[PersonViewController alloc] init] autorelease];
personViewController.person = ... // get the selected person
personViewController.managedObjectContext = self.managedObjectContext;
[self.navigationController pushViewController:personViewController animated:YES];

PersonViewController 具有以下属性:

@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) Person *person;
@property (nonatomic, copy) NSArray *images;

有一个添加按钮可以显示图像选择器

- (void)insertNewObject 
    UIImagePickerController *imagePicker = [[[UIImagePickerController alloc] init] autorelease];
    imagePicker.delegate = self;
    [self presentModalViewController:imagePicker animated:YES];

那么在回调imagePickerController:didFinishPickingMediaWithInfo:我们可以:

// Get the image from the picker
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];

// Transform the image to NSData
ImageToDataTransformer *transformer = [[[ImageToDataTransformer alloc] init] autorelease];
NSData *imageData = [transformer transformedValue:image];

// Create a new PersonImage entity and assign the image data    
PersonImage *personImage = [NSEntityDescription insertNewObjectForEntityForName:@"PersonImage" inManagedObjectContext:self.managedObjectContext];
personImage.imageData = imageData;

// This is where we are adding the image to our person  
[self.person addImagesObject:personImage];

// Core data save, however you want to do it.
NSError *error = nil;
if (![self.managedObjectContext save:&error]) 
    abort();


// simple trick to update the table view data source    
self.images = nil;
[self.tableView reloadData];
// don't forget to dismiss the picker
[self dismissModalViewControllerAnimated:YES];

images 的实现只是为了简单

- (NSArray *)images 
    if (images_) 
        return images_;
    

    // since we set self.images = nil when adding a new image we will get the list
    // of all images from our person object. 
    images_ = [[self.person.images allObjects] retain];
    return images_;

表格视图数据源方法只是:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    return 1;



- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    return self.images.count;

但是,创建单元格并不重要。那时,如果我们想对图像做点什么,我们可以在 tableView:didSelectRowAtIndexPath: 中做点什么

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
  // get the tapped person image    
  PersonImage *personImage = [self.images objectAtIndex:indexPath.row];
  // get the image
  ImageToDataTransformer *transformer = [[[ImageToDataTransformer alloc] init] autorelease];
  UImage *image = [transformer reverseTransformedValue:personImage.imageData];
  // do something with the image.


【讨论】:

为罗伯特干杯。让我根据您的代码检查我的 imagePickerController:didFinishPickingMediaWithInfo。我的和你的很相似,但一定有我遗漏的东西。请稍后来检查。 我错过的是在“personImage.imageData = imageData;”之前我没有将图像数据更改为 NSData。似乎没有警告或错误消息,所以让我问你一个问题。稍后您使用 NSArray 图像来获取 PersonImage。我不知道我们为什么需要它,因为一旦我们使用多对多关系将一个人的多个图像保存到 Core Data 中,那么必须有一种方法可以以相同的方式获取这些图像。 我想我明白了。只是设法将多个图像保存到实体上并一一检查。伟大的! (当然还有很多事情要做)“除了将 UIImage 转换为 NSData 并返回之外,与 UIImage 建立一对多关系并没有什么特别的。” ,您的代码和 CoreDataRecipe(每次我查看此示例时都会给我一些新的东西……)“非常”有帮助。谢谢。 二审。它是“添加和检查”多个图像到一个我成功的实体而不是“保存”。添加和保存是不同的..所以我在***.com/questions/4282416/… 发布了另一个问题。干杯。【参考方案2】:

来自相机的图像可能非常大。 Core Data 中图像的一般规则是低于 1 MB。您可能希望将图像存储在目录中,并将路径存储在 Core Data 中。

【讨论】:

当我在设备上测试我的一个人和一张图片(一对一关系)的应用程序时,性能还不错。非常感谢您的建议..要学习的东西太多....

以上是关于在“多对多关系”环境中将图片保存在 Core Data 中的主要内容,如果未能解决你的问题,请参考以下文章

EF Core中通过Fluent API配置多对多关系

EF Core中通过Fluent API配置多对多关系

EF Core中通过Fluent API配置多对多关系

EF Core中通过Fluent API配置多对多关系

如何在 EF Core 中查询多对多关系

在 Swift 中将 NSManagedObject 添加到 CoreData 多对多关系时防止循环