处理对多关系中 Core Data 对象的删除

ndg*_*ndg 2 iphone core-data ios

使用 Core Data,我希望建立一个具有以下对多关系的标记系统:

article.tags <<------->> tag.articles
Run Code Online (Sandbox Code Playgroud)

在这种情况下, anarticle可以有多个tags,并且tags可以将这些相同的分配给多个articles。每当 anarticle的标签被编辑时,我会删除所有以前tags与 相关的标签,article并重新添加那些仍然相关的标签,如下所示:

// Remove any existing tags from this article
if(article.tags.count)
{
    NSSet *existingEventTags = [article.tags copy];
    for (NSManagedObject *tag in existingEventTags)
    {
        [[article mutableSetValueForKey:@"tags"] removeObject:tag];
        [moc deleteObject:tag];
    }
}

// Now re-assign any applicable tags to this article
for(NSString *tag in tags)
{
    Tag *existingTag = [self existingTagWithString:tag];
    if(existingTag)
    {
        [article addTagsObject:existingTag];
    }
    else
    {
        NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Tag" inManagedObjectContext:moc];
        Tag *newTag = (Tag *)[[NSManagedObject alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:moc];
        newTag.name = tag;
        [article addTagsObject:newTag];
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是如何最好地处理与这两个关系关联的删除规则。基本上,我正在寻找的行为是,当我tag从 an 中删除 a时article,如果没有其他articles标记,我只想完全删除它。

为了实现这一点,我将我的tag.articles关系设置为 Nullify,并将我的articles.tags关系设置为 Cascade。然而,当删除一篇文章时,任何与其相关的标签(无论它们是否与其他文章相关)都会被删除。为了测试这一点,我编写了一个简单的调试函数,我将在下面包含它:

- (void)debugTags
{
    NSFetchRequest *request = [[NSFetchRequest alloc] init];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Tag" inManagedObjectContext:moc];
    [request setEntity:entity];

    // Execute the fetch.
    NSError *error = nil;
    NSArray *objects = [moc executeFetchRequest:request error:&error];
    if (objects != nil && [objects count] > 0)
    {
        NSLog(@"Found %d tags", [objects count]);
        for(Tag *tag in objects)
        {
            NSLog(@"\t%@ (%d events)", tag.name, tag.articles.count);
        }
    }
    else
    {
        NSLog(@"No tags found!");
    }
}
Run Code Online (Sandbox Code Playgroud)

为了完整起见,这里有一个示例输出(显示articles两个共享的创建tags:食物和快餐)。删除 one 后article,我希望仍然可以在商店中找到食物和快餐,但关系计数为 1。

Before deletion
---------------

Found 4 tags
   breakfast (1 events)
   food (2 events)
   fastfood (2 events)
   lunch (1 events)

After deletion
--------------

Found 1 tags
   lunch (1 events)
Run Code Online (Sandbox Code Playgroud)

ndg*_*ndg 5

我发现这个问题的最佳解决方案是将两个删除规则都设置为 Nullify,并在 myarticleNSManagedObject prepareForDeletion方法中处理删除:

- (void)prepareForDeletion
{
    [super prepareForDeletion];

    for (Tag *tag in self.tags)
    {
        if(tag.events.count == 1)
        {
            [self.managedObjectContext deleteObject:tag];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)