iphone,将数据保存到多个关系中,核心数据

iphone,将数据保存到多个关系中,核心数据,iphone,core-data,entity-relationship,save,one-to-many,Iphone,Core Data,Entity Relationship,Save,One To Many,我正在使用核心数据开发一个小型iphone应用程序,在这个应用程序中,我得到了一个人和一个图像实体。人与形象之间的关系是多方面的。一个人对多个图像 问题发生在save方法中。首先在保存过程中,我需要将从ImagePickerViewController获得的多个图像数据“添加”到Person,然后将Person实体“保存”到实际数据库。((用同样的方法)) 然后我得到一个错误,说: "-[NSConcreteMutableData CGImage]: unrecognized selecto

我正在使用核心数据开发一个小型iphone应用程序,在这个应用程序中,我得到了一个人和一个图像实体。人与形象之间的关系是多方面的。一个人对多个图像

问题发生在save方法中。首先在保存过程中,我需要将从ImagePickerViewController获得的多个图像数据“添加”到Person,然后将Person实体“保存”到实际数据库。((用同样的方法))

然后我得到一个错误,说:

"-[NSConcreteMutableData CGImage]: unrecognized selector sent to instance" 
以及:

我猜错误来自于从一个managedObjectContext中重复使用NSEntityDescription。所以我只初始化Person类,它自动从数据模型派生并手动导入,就像注释行一样,而不是使用managedObjectContext

当我点击保存按钮时,它没有给出任何错误,但给出了运行时错误

当我使用一对一关系时,保存并没有问题,所以我想对Person使用managedObjectContext是正确的方法。然而,一旦我使用多个关系,我需要将图像数据保存到PersonImage实体。实体必须以某种方式初始化

我错过了什么?

好吧

我查看了您发布在GitHub上的代码,发现您的DetailView控制器存在一些问题,我将在下面概述这些问题

首先,您没有正确地将托管对象上下文传递到详细视图,这意味着当您试图保存对象时,没有上下文可供保存。将托管对象上下文视为持久存储的“草稿”。您对NSManagedObject所做的任何更改都将被跟踪并保留在您的上下文中,直到您使用
[managedObjectContext save]
命令将其持久化

因此,为了清楚起见,您正在AppDelegate中创建上下文,然后使用
RootViewController.managedObjectContext=self.managedObjectContext

从RootViewController,您需要使用相同的技术将managedObjectContext向下传递到DetailView。因此,在您的
tableView:didSelectRowAtIndexPath:
方法中,您应该传递对上下文的引用,以便跟踪您对该视图所做的任何更改,并最终将其持久化:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {    
     DetailView *detailView = [[DetailView alloc] initWithNibName:@"DetailView" bundle:nil];
     detailView.event = (Event *)[[self fetchedResultsController] objectAtIndexPath:indexPath];
     detailView.managedObjectContext = self.managedObjectContext;

     // ...
     [self.navigationController pushViewController:detailView animated:YES];
     [detailView release];
}
我还更新了对managedObjectContext的所有其他引用,您在其中实例化了一个新的上下文对象,以简单地指向self.managedObjectContext,即:

JustString *_justString = [NSEntityDescription insertNewObjectForEntityForName:@"JustString" inManagedObjectContext:self.managedObjectContext];
一旦排除了这个问题,只有一件事会阻止您正确保存图像对象,TechZen在上面提到了这一点

在DetailView控制器中,您有一个
imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info{
方法,在该方法中,您可以将UIImage转换为NSData,然后将其分配给图像实体实例

问题是,您的对象模型(参见Event.m)中已经有一个名为
-(id)transformedValue:(id)value
的transformer方法

因此,基本上您尝试将UIImage转换为NSData,然后将NSData传递给实体,实体实际上需要UIImage。在这种情况下,我建议您让对象模型处理数据转换,因此在DetailView控制器中,将UIImage注释为NSData transformer代码,并将映像di传递给实体直接连接到托管对象:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
    UIImage *selectedImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    // Transform the image to NSData
    // ImageToDataTransformer *transformer = [[[ImageToDataTransformer alloc] init] autorelease];
    // NSData *imageData = [transformer transformedValue:selectedImage];
    Image *_image = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:self.managedObjectContext];    
    _image.justImage = selectedImage;
    [event addEventToImageObject:_image];
    [picker dismissModalViewControllerAnimated:YES];
}
在那之后,你应该很乐意去尝试一下,让我们知道它是否解决了你的问题

CoreData的学习曲线可能有点陡峭,但一旦你“掌握了它”,你就会意识到它是iOS开发中最精美的API之一

祝你好运,让我们知道你进展如何! 好的

我查看了您发布在GitHub上的代码,发现您的DetailView控制器存在一些问题,我将在下面概述这些问题

首先,您没有正确地将托管对象上下文传递到详细视图,这意味着当您试图保存对象时,没有上下文可供保存。请将托管对象上下文视为“草稿”您对NSManagedObject所做的任何更改都将被跟踪并保留在您的上下文中,直到您使用
[managedObjectContext save]
命令将其持久化

因此,为了清楚起见,您正在AppDelegate中创建上下文,然后使用
RootViewController.managedObjectContext=self.managedObjectContext

从RootViewController,您需要使用相同的技术将managedObjectContext向下传递到DetailView。因此,在
tableView:DidSelectRowatineXpath:
方法中,您应该传递对上下文的引用,以便跟踪您对该视图所做的任何更改,并最终将其持久化:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {    
     DetailView *detailView = [[DetailView alloc] initWithNibName:@"DetailView" bundle:nil];
     detailView.event = (Event *)[[self fetchedResultsController] objectAtIndexPath:indexPath];
     detailView.managedObjectContext = self.managedObjectContext;

     // ...
     [self.navigationController pushViewController:detailView animated:YES];
     [detailView release];
}
我还更新了对managedObjectContext的所有其他引用,您在其中实例化了一个新的上下文对象,以简单地指向self.managedObjectContext,即:

JustString *_justString = [NSEntityDescription insertNewObjectForEntityForName:@"JustString" inManagedObjectContext:self.managedObjectContext];
一旦排除了这个问题,只有一件事会阻止您正确保存图像对象,TechZen在上面提到了这一点

在DetailView控制器中,您有一个
imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info{
方法,在该方法中,您可以将UIImage转换为NSData,然后将其分配给图像实体实例

问题是,您的对象模型(参见Event.m)中已经有一个名为
-(id)transformedValue:(id)value
的transformer方法

因此,基本上,您尝试将UIImage转换为NSData,然后将NSData传递给实体,实体实际上需要UIImage
JustString *_justString = [NSEntityDescription insertNewObjectForEntityForName:@"JustString" inManagedObjectContext:self.managedObjectContext];
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
    UIImage *selectedImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    // Transform the image to NSData
    // ImageToDataTransformer *transformer = [[[ImageToDataTransformer alloc] init] autorelease];
    // NSData *imageData = [transformer transformedValue:selectedImage];
    Image *_image = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:self.managedObjectContext];    
    _image.justImage = selectedImage;
    [event addEventToImageObject:_image];
    [picker dismissModalViewControllerAnimated:YES];
}