在核心数据中插入新的关系数据

Posted

技术标签:

【中文标题】在核心数据中插入新的关系数据【英文标题】:inserting new relationship data in core-data 【发布时间】:2010-04-06 12:06:11 【问题描述】:

我的应用将允许用户从大量事件列表中创建个性化的事件列表。我有一个表格视图,它只显示这些事件,点击其中一个会将用户带到事件详细信息视图,该视图有一个“添加到我的事件”按钮。

在此详细视图中,我拥有原始事件对象,通过 NSFetchedResultsController 检索并传递到详细视图(通过表格单元格,与核心数据配方示例相同)。我可以毫无问题地从此“事件”中检索/显示信息。然后我尝试将其添加到由一对多(反向)关系表示的MyEvents 列表中:

alt text http://www.imgplace.com/img580/8008/44relationship.png

这段代码:

NSManagedObjectContext *context = [event managedObjectContext];
MyEvents *myEvents = (MyEvents *)[NSEntityDescription insertNewObjectForEntityForName:@"MyEvents" inManagedObjectContext:context];
[myEvents addEventObject:event];//ERROR

还有这段代码(建议如下):

//would this add to or overwrite the "list" i am attempting to maintain
NSManagedObjectContext *context = [event managedObjectContext];
MyEvents *myEvents = (MyEvents *)[NSEntityDescription insertNewObjectForEntityForName:@"MyEvents" inManagedObjectContext:context];
NSMutableSet *myEvent = [myEvents mutableSetValueForKey:@"event"];
[myEvent addObject:event]; //ERROR

机器人生产(在 //ERROR 指示的行):

*** -[NSComparisonPredicate evaluateWithObject:]: message sent to deallocated instance

似乎我错过了一些基本的东西。以我的了解,我无法通过使用调试工具收集更多信息。

1) 这是编译和存储这样的可编辑列表的有效方法吗?

2) 有没有更好的方法?

3) 什么可能是错误的释放实例?

--

我现在已经修改了 Event 实体,使其具有称为“myEvents”的一对多关系,它引用自身。我可以将事件添加到这很好,并且记录对象会显示在[event addMyEventObject:event]; 之后出现的关系的正确内存地址。然而,同样的失败发生在这之后。我仍然不知道出了什么问题。这是回溯

#0  0x01f753a7 in ___forwarding___ ()
#1  0x01f516c2 in __forwarding_prep_0___ ()
#2  0x01c5aa8f in -[NSFetchedResultsController(PrivateMethods) _preprocessUpdatedObjects:insertsInfo:deletesInfo:updatesInfo:sectionsWithDeletes:newSectionNames:treatAsRefreshes:] ()
#3  0x01c5d63b in -[NSFetchedResultsController(PrivateMethods) _managedObjectContextDidChange:] ()
#4  0x0002e63a in _nsnote_callback ()
#5  0x01f40005 in _CFXNotificationPostNotification ()
#6  0x0002bef0 in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#7  0x01bbe17d in -[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] ()
#8  0x01c1d763 in -[NSManagedObjectContext(_NSInternalChangeProcessing) _createAndPostChangeNotification:withDeletions:withUpdates:withRefreshes:] ()
#9  0x01ba25ea in -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] ()
#10 0x01bdfb3a in -[NSManagedObjectContext processPendingChanges] ()
#11 0x01bd0957 in _performRunLoopAction ()
#12 0x01f4d252 in __CFRunLoopDoObservers ()
#13 0x01f4c65f in CFRunLoopRunSpecific ()
#14 0x01f4bc48 in CFRunLoopRunInMode ()
#15 0x0273878d in GSEventRunModal ()
#16 0x02738852 in GSEventRun ()
#17 0x002ba003 in UIApplicationMain ()

解决方案

我设法弄明白了。

我正在使用NSFetchedResultsControllerNSPredicate 获取相关事件,我在获得结果后发布了该事件。从返回的实体中检索值没有问题,但是当我尝试更新其中任何一个时,它给出了上述错误。它不应该被释放。

我的问题中突出的部分

根据核心数据模型,从现有项目列表创建此子列表的好方法是什么。我不相信我在这里尝试过的任何方式。我需要在另一个表格视图中显示/编辑它。也许有比每个事件实体上的布尔属性更好的方法?上面的关系想法在这里似乎行不通(尽管我现在可以创建它)。

干杯。

【问题讨论】:

为什么需要 MyEvents?如果您仅将其用作容器对象,请改用NSFetchedResultsController 我认为您可能仍然不需要单独的实体。您可以创建从 Event 到自身的一对多关系,类似于 Employee - manager > directReports 关系。在这种情况下,您可以创建 Event - favoriteEvent > 收藏夹。查看developer.apple.com/mac/library/documentation/DeveloperTools/… 我尝试了类似的方法 - 请参阅有问题的更新;也许我的模型现在不是最好的,但我认为这不是我所看到的问题的原因。 【参考方案1】:

假设您已命名MyEvents <--->> Event relationship as events

MyEvents *myEvents = (MyEvents *)[NSEntityDescription insertNewObjectForEntityForName:@"MyEvents" inManagedObjectContext:context];

NSLog(@"MYEVENTS: %@", myEvents);
NSLog(@"EVENT: %@", event);

// NSMutableSet to hold the events
NSMutableSet *events = [event mutableSetValueForKey:@"events"];

// Add the event to the set. Core Data takes care of the rest
[events addObject:event];

根据我的评论,考虑一下为什么要创建一个新实体来管理集合。 NSFetchedResultsControllerNSFetchedResultsControllerDelegate 协议旨在与 tableViews 密切合作。有关如何使用这些类的信息,请参阅 Apple 文档。

【讨论】:

我这样做是因为我不需要在需要修改数据的地方使用 NSFetchedResultsController。我使用 NSFetchedResultsController 在表视图中检索“事件”,然后将此“事件”传递给另一个仅与此“事件”有关的视图控制器。如果用户启动此操作,我将尝试将其添加到“MyEvents”列表中。我想 Event 实体中可能有一个属性,说明这是否要构成用户 MyEvents 的一部分。不过,我可能想在“MyEvents”中添加更多信息。 您是否尝试过我回答中的代码?查看CoreDataBooks 示例代码,研究RootViewController、DetailViewController 和EditingViewController 之间的交互。您似乎正在尝试实施类似的工作流程。 感谢您的帮助和耐心 falconcreek。我确实尝试了您建议的代码,并更新了我原来的问题。我确实在尝试与书籍示例代码类似的东西,但我正在尝试将我已经拥有的信息添加到列表中,而不是添加一个全新的实体。我传递与食谱示例代码相同的引用。【参考方案2】:

我可以看到这是一个老问题,所以你可能已经克服了这个障碍,但你绝对不需要为 MyEvent 单独的实体。

如果你走这条路,如果这是你的项目的要求,你将不得不做很多工作来保持事件和我的事件视图同步。

解决您的问题的最简单方法是简单地将“收藏夹”属性添加到您的 Event 实体(可以通过 UIButton 或您在界面中喜欢的任何内容进行切换),然后将 NSFetchedResultsController 与 (favourites == YES ) 谓词来处理您的“我的事件”视图。

这样您只处理一个实体,NSFetchedResultsController 会在需要时为您更新视图。

【讨论】:

以上是关于在核心数据中插入新的关系数据的主要内容,如果未能解决你的问题,请参考以下文章

核心数据:使用 To many 关系插入和删除

将新的核心数据对象插入到多个 NSOrderedSet 会忽略索引

核心数据:非法尝试建立关系+(空)上下文

核心数据关系,如何从关系中插入和检索数据

使用关系从核心数据数据库中删除所有表记录

Swift3 - 在核心数据中插入关系