如何在关系变空时删除托管对象

时间:2011-08-22 18:38:26

标签: iphone objective-c ios xcode core-data

我目前正在开发我的第一个iPhone核心数据项目。经过一些实验,我对核心数据中的实体关系有一些相当基本的问题。

假设我有两个实体:事件和位置。每个都有一个name属性。一个事件只能有一个位置,而一个位置可以有多个事件。所以关系看起来像这样:

Event <<--> Location

在我的项目中,我(用户)可以输入事件及其位置的名称。然后我基于该输入为Event实体创建一个新对象。我通过访问事件的关系来设置位置的名称:

event.Location.name = someCustomString;

保存工作正常。我想。

我的第一个问题是:

每次执行此操作时,Core Data是否为Location实体创建了一个新对象 - 即使之前使用过相同的Location名称(并且仍然存储)?或者,在这种情况下,Core Location是否仅自动设置与现有Location对象的关系?因为对于我的项目,有必要识别发生在同一位置的事件。

这也引出了我的下一个问题:

删除Event对象怎么样?当我这样做时,我必须检查多个事件是否使用相应的位置。如果是,我将使关系无效但保留Location对象。如果没有,我也必须删除Location对象。我当前的方法(基于我的假设,即具有相同名称的位置不会被双重保存)看起来像这样:

Event *event = (event *)[appManager.results.fetchedObjects objectAtIndex:indexPath.row];

    NSInteger locationEvents = 0;

    for (Event *eve in appManager.results.fetchedObjects) 
    {
        if (eve.Location.name == event.Location.name) 
        {
            locationMoments++;
        }
    }

    if (locationMoments == 1) 
    {
        [appManager.managedObjectContext deleteObject:event.Location];
    }

    [appManager.managedObjectContext deleteObject:event];

所以至少我认为我正在检查某个Location对象引用的事件数。但是代码感觉有点痒......我不知道这是不是正确的做法。所以我的最后一个问题是: 我的方案中的标准程序是什么?如果有的话。 ;)

提前感谢大家的答案!

2 个答案:

答案 0 :(得分:0)

  

Core Data是否每次都为Location实体创建一个新对象   我这样做

不,event.Location.name是一个关键路径,它将关系从Event实例“移动”到Location实例,然后访问属性name。密钥路径仅适用于现有对象。

但是,由于您有一个Location个对象与许多Event个对象共享,因此使用任何一个Location.name对象更改Event值会更改所有{{1}的值共享该Event个对象的对象。

如果希望托管对象在关系变空时立即删除自身,则将删除代码放在该类的Location访问器方法中。当关系达到零时,让对象告诉上下文删除它。这使得您可以将代码放在一个地方,而不是在可能改变关系的任何地方展开。

如果您只想在保存上下文时删除对象,请将代码放在类“remove…方法中。这将在下次保存上下文时触发删除。

答案 1 :(得分:0)

非常感谢您的帮助TechZen。现在我想我更了解核心数据。我也让我的数据模型工作。事实证明,当我创建我的实体和相应的子类时,我忘了将实体的类设置为检查器中创建的文件。 (想想会自动设置 - 因为文件也是自动创建的。)所以我的Location实体的willSave方法从未被调用过。我解决了这个问题,并整理出如何以正确的方式处理关系。正如我所说,我使用了一个带有简单&#34; name ==%@&#34;的获取请求。谓词以查找以前使用的位置名称。 ;)

但毕竟我也使用实际位置数据(纬度,经度)。即使位置及其名称相同,位置的坐标也会略有不同。所以我必须找到一种方法来比较存储的坐标和当前用户位置的坐标。当用户靠近以前使用过的位置并使用该名称时,新的坐标数据应该覆盖旧的 - 或者它应该保持不变,新的事件将被分配旧的位置。如果您有任何想法,我也要感激不尽!但我想我知道该怎么做 - 主要是。 :)