核心数据关系中出现不需要的对象

时间:2013-08-05 02:32:22

标签: ios core-data

冗长的问题---提前感谢你的时间。保存新的托管对象后,我发现它们被添加到我的核心数据库中另一个对象的关系中 - 我的代码没有调用setter方法,并且没有反向关系。我仔细研究了代码,并使用日志来尽可能地隔离事件,但我遇到了奇怪的行为,我无法解释(或修复)。

更具体地说:

我有一个名为PendingSyncTracker的实体。它只有一个关系,objectsToSync。我还没有在我的代码中添加任何行来调用此关系的setter方法。这是一种多对多的关系。它指向BaseEntity。对于“反向”选项,我选择了“无反向关系”。

当我加载特定的表视图时,从服务器下载3个对象,然后解析为托管对象并保存。当表视图开始加载单元格时,这3个对象中的2个将神秘地存在于objectsToSync关系中。

我在我的代码中使用NSLog来确定何时可以首先找到这些对象作为objectsToSync集的成员。

NSSet *objectsToSync = [[[SyncEngine sharedEngine] fetchClassNamed:@"PendingSyncTracker" withPredicates:nil][0] valueForKey:@"objectsPendingSync"];
NSLog(@"PendingSyncTracker objectsToSync set (%lu objects): %@", (unsigned long)[objectsToSync count], objectsToSync);

它们首次出现在集合中的答案实际上取决于我做/不放置这两行代码的位置!

  • 在保存我的3个新核心数据对象的过程中,在保存托管对象上下文之前,从未在关系中找到对象。

  • 如果我不使用这两行,直到我回到表视图控制器中,它将新对象发送到同步引擎以存储在本地(访问和保存MOC),然后日志将显示已在关系中添加了2个对象。

  • 如果我在同步引擎中保存MOC后立即使用这2行,那么日志将指示(TVC中的那里和后面)只有1个对象被添加到关系中。

  • 如果我在保存MOC之前和之后立即使用这2行(并返回到TVC中),那么所有3个日志都会显示该关系包含空集。

  • 我在cellForRowAtIndexPath的开头也有这两行。无论先前的日志如何,该日志将始终指示已将2个对象添加到关系中。

在同步引擎中创建的所有3个托管对象都存储为实体类型,这些实体类型是BaseEntity的子实体(objectsToSync关系点所指向的)。添加到关系中的两种类型都被定义为具有倒数关系,但是具有不同的对象,而不是PendingSyncTracker(尽管不同的对象是BaseEntity的子实体!)。

那么......是什么解释了这些观察结果?这些对象如何被添加到关系中?

更新:

- (NSArray*) fetchClassNamed:(NSString*)className withPredicates:(id)parameters;
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:className inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // set predicates
    if (!(parameters == nil)) {
        [fetchRequest setPredicate:parameters];
    }

    NSError *error;
    NSArray *fetchedResults = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];

    return fetchedResults;
}

1 个答案:

答案 0 :(得分:1)

首先,[[[SyncEngine sharedEngine] fetchClassNamed...做了什么?只是一个猜测,但它正在与KVC做一些事情来为你设置关系。

此外,您应始终始终始终具有反向关系。即使你从不使用它,Core Data也可以。没有逆可能导致许多问题,包括但不限于性能问题和潜在的数据损坏。

添加反向关系,并使用-fetchClassNamed...的内容更新您的问题。