iOS Core Data 对多关系插入/获取

Posted

技术标签:

【中文标题】iOS Core Data 对多关系插入/获取【英文标题】:iOS Core Data to-many relationship insert/fetch 【发布时间】:2013-11-25 03:29:00 【问题描述】:

在我的应用程序中,我有旅行,其中有很多站点。这已在 .xcdatamodeld 文件中指定。我可以以任何我想要的方式进行操纵旅行,而且它们都可以正常工作。但是,我遇到了为每次旅行添加许多站点的问题。它似乎没有持续存在。这是以下代码。此代码位于行程的 detailViewController 中,因此已单击特定行程。

Trip * trip = [self retrieveObjectWithID:_passedObjectId];


    StopOff *newStop = [NSEntityDescription insertNewObjectForEntityForName:@"StopOff" inManagedObjectContext:managedObjectContext];

    [newStop setValue:stopName forKey:@"stopName"];
    [newStop setValue:stopCity forKey:@"stopCity"];
    [newStop setValue:stopDate forKey:@"stopDate"];
    [newStop setValue:stopAddress forKey:@"stopAddress"];
    [newStop setValue:stopState forKey:@"stopState"];
    [newStop setValue:stopTime forKey:@"stopTime"];

    newStop.trip = trip;
    [trip addStopObject:newStop];

    NSLog(@" stop count %i", [trip.stop count]);

这是我第一次点击按钮运行时控制台输出的内容:CoreData: annotation: to-many relationship fault "stop" for objectID 0x8bb2810 <x-coredata://4CE70783-4729-46E0-B18B-8E325D1020CC/Trip/p20> fulfilled from database. Got 0 rows 2013-11-24 21:19:43.417 Tracker[30633:70b] stop count 1

如果我继续按下按钮,停止计数会增加。如果我重新启动应用程序,停止计数会回落并重新开始,所以它似乎没有持续存在。

我的问题是,我如何准确地插入与行程相对应的许多站点,一旦插入并保持它们,我如何继续并获得与该行程对应的每个站点。

这是检索每次行程的代码。而managedObjectContext 在父视图控制器中使用NSFetchedResultsController 处理。如果您需要更多信息,请告诉我

- (Trip*)retrieveObjectWithID:(NSManagedObjectID*)theID

    NSError *error = nil;
    Trip *theObject = (Trip*)[self.managedObjectContext existingObjectWithID:theID error:&error];
    if (error)
        NSLog (@"Error retrieving object with ID %@: %@", theID, error);
    return theObject;

【问题讨论】:

您是否将新的StopOff 对象保存在任何地方? 我想我不太清楚你的意思是什么,我认为 insertNewObjectForEntityForName 会解决这个问题。当我返回父视图控制器然后返回该特定行程时,停止计数对于特定行程正确保留。如果应用程序退出,它不会。 要检索一次旅行的所有停靠点,只需使用trip.stops(或者在您的情况下,您似乎已经调用了To-Many关系trip.stop),它将返回一个StopOff对象的NSSet。 【参考方案1】:

应用更改后,您没有保存上下文(新的StopOff 对象)。

添加StopOff 后,调用[managedObjectContext save:&error],您会将新对象持久化到存储中。

CoreData 不会自动保存,如果不调用 save:,您将丢失对上下文所做的任何临时更改。

另外,也不需要[trip addStopObject:newStop];,因为 CoreData 将其作为反向关系的一部分来处理。

【讨论】:

太棒了!谢谢!完成此操作后,我如何获取并获取属于某个行程的所有站点? CoreData 是一个对象图,一个简单的方法是访问trip.stop (NSSet) 并获取您指定的停靠点。 如何删除其中一个站点? 与任何NSManagedObject 子类一样:[context deleteObject:obj];,然后保存删除。这也会从对多关系中删除对象,因此无需自己删除。【参考方案2】:

您有一个多对多关系设置:您不需要newStop.trip = trip[trip addStopObject:newStop]。我认为这就是您收到警告的原因。

在某些时候,你会想要调用:

NSError *error = nil;
[managedObjectContext save:&error];

【讨论】:

以上是关于iOS Core Data 对多关系插入/获取的主要内容,如果未能解决你的问题,请参考以下文章

IOS/Core-Data:添加多对多关系

Core Data 无法删除从未插入的对象错误

对于我的多对多关系,Core Data 获取速度非常慢?

Core Data Fetch 在插入实体时保存关系(同时)

Core Data + iCloud,更改通知插入和删除关系中的对象但不更新关系中现有实体的属性

Flask sqlalchemy 多对多插入数据