【问题标题】:Core Data relationship delete rule - Nullify + CascadeCore Data 关系删除规则 - Nullify + Cascade
【发布时间】:2012-04-15 14:14:40
【问题描述】:

实体:

  • 视频
  • 播放列表项
  • 播放列表

关系:

  • 视频对于播放列表项是可选的,删除规则无效
  • 播放列表对至少一个播放列表项是一对多且删除规则无效
  • 视频需要一对一播放列表项,删除规则无效
  • Playlist Item 需要一对一,删除规则无效

在 Playlist 实体中,我没有暴露 playlistItem 关系/集合。相反,我有一个名为“videos”的临时未定义属性,它是通过对播放列表项集进行排序生成的视频实体数组。播放列表和视频实体之间没有关系。

在托管对象上下文中保存修改后的播放列表实例时遇到问题。

来自 playlist.m(NSManagedObject 子类):

- (BOOL)validatePlaylistItems:(NSSet **)playlistItems error:(NSError **)outError
{
    NSArray *currentVideos = [self videos];
    NSArray *persistedVideos = [self videosFromPlaylistItems];

    if ([currentVideos isEqual:persistedVideos]) {
        return YES;
    }

    NSManagedObjectContext *context = [self managedObjectContext];
    for (FHPlaylistItem *pi in *playlistItems) {
        [context deleteObject:pi];
    }

    NSArray *videos = [self primitiveVideos];
    NSUInteger count = [videos count];
    for (int i = 0; i < count; i++) {
        FHPlaylistItem *pi = [FHPlaylistItem playlistItemWithVideo:[videos objectAtIndex:i]
                                                          forIndex:i
                                    insertIntoManagedObjectContext:[self managedObjectContext]];
        [self addPlaylistItemsObject:pi];
        [pi setPlaylist:self];
    }

    return YES;
}

我在这里尝试完成的只是在 MOC 需要保存时更新播放列表项集,因为您可以看到该操作很昂贵 - O(N * 2)。在应用程序的第一次运行期间,MOC 保存得很好。然而,随后对视频属性的更改会在 Core Data 中产生一系列错误:

Core Data: annotation: repairing missing delete propagation for to-many relationship playlistItems on object <FHPlaylist: 0x6c27eb0> (entity: Playlist; id: 0x6c26d40 <x-coredata://BCB69D8E-8393-4A2A-AF5D-0AA1872CE2B4/Playlist/p19> ; data: {
    accountID = 0;
    lastFetched = "2012-03-31 20:05:08 +0000";
    name = Featured;
    playlistID = 1441335931001;
    playlistItems =     (
        "0x6c34be0 <x-coredata:///PlaylistItem/t9EAFBC87-5E16-4053-984F-881CCD9C1F0B2>",
        "0x6c34320 <x-coredata://BCB69D8E-8393-4A2A-AF5D-0AA1872CE2B4/PlaylistItem/p16>",
        "0x6c310c0 <x-coredata:///PlaylistItem/t9EAFBC87-5E16-4053-984F-881CCD9C1F0B3>",
        "0x6c35570 <x-coredata:///PlaylistItem/t9EAFBC87-5E16-4053-984F-881CCD9C1F0B5>",
        "0x6c34ca0 <x-coredata:///PlaylistItem/t9EAFBC87-5E16-4053-984F-881CCD9C1F0B6>",
        "0x6c34310 <x-coredata://BCB69D8E-8393-4A2A-AF5D-0AA1872CE2B4/PlaylistItem/p8>",
        "0x6c28a90 <x-coredata:///PlaylistItem/t9EAFBC87-5E16-4053-984F-881CCD9C1F0B4>",
        "0x6c34350 <x-coredata://BCB69D8E-8393-4A2A-AF5D-0AA1872CE2B4/PlaylistItem/p29>",
        "0x6c34220 <x-coredata://BCB69D8E-8393-4A2A-AF5D-0AA1872CE2B4/PlaylistItem/p2>",
        "0x6c34330 <x-coredata://BCB69D8E-8393-4A2A-AF5D-0AA1872CE2B4/PlaylistItem/p20>",
        "(...and 1 more...)"
    );
    playlistType = 0;
    referenceID = OKFFeaturedPlaylist;
    shortDescrip = "This is so descriptive! OMG!";
    thumbnailURL = nil;
    videos = "(...not nil..)";
}) with bad fault 0x6c34320 <x-coredata://BCB69D8E-8393-4A2A-AF5D-0AA1872CE2B4/PlaylistItem/p16>
Core Data: annotation: repairing missing delete propagation for to-many relationship playlistItems on object <FHPlaylist: 0x6c27eb0> (entity: Playlist; id: 0x6c26d40 <x-coredata://BCB69D8E-8393-4A2A-AF5D-0AA1872CE2B4/Playlist/p19> ; data: {
    accountID = 0;
    lastFetched = "2012-03-31 20:05:08 +0000";
    name = Featured;
    playlistID = 1441335931001;
    playlistItems =     (
        "0x6c34be0 <x-coredata:///PlaylistItem/t9EAFBC87-5E16-4053-984F-881CCD9C1F0B2>",
        "0x6c310c0 <x-coredata:///PlaylistItem/t9EAFBC87-5E16-4053-984F-881CCD9C1F0B3>",
        "0x6c35570 <x-coredata:///PlaylistItem/t9EAFBC87-5E16-4053-984F-881CCD9C1F0B5>",
        "0x6c34ca0 <x-coredata:///PlaylistItem/t9EAFBC87-5E16-4053-984F-881CCD9C1F0B6>",
        "0x6c34310 <x-coredata://BCB69D8E-8393-4A2A-AF5D-0AA1872CE2B4/PlaylistItem/p8>",
        "0x6c28a90 <x-coredata:///PlaylistItem/t9EAFBC87-5E16-4053-984F-881CCD9C1F0B4>",
        "0x6c34350 <x-coredata://BCB69D8E-8393-4A2A-AF5D-0AA1872CE2B4/PlaylistItem/p29>",
        "0x6c34220 <x-coredata://BCB69D8E-8393-4A2A-AF5D-0AA1872CE2B4/PlaylistItem/p2>",
        "0x6c34330 <x-coredata://BCB69D8E-8393-4A2A-AF5D-0AA1872CE2B4/PlaylistItem/p20>",
        "0x6c34340 <x-coredata://BCB69D8E-8393-4A2A-AF5D-0AA1872CE2B4/PlaylistItem/p27>"
    );
    playlistType = 0;
    referenceID = OKFFeaturedPlaylist;
    shortDescrip = "This is so descriptive! OMG!";
    thumbnailURL = nil;
    videos = "(...not nil..)";
}) with bad fault 0x6c34310 <x-coredata://BCB69D8E-8393-4A2A-AF5D-0AA1872CE2B4/PlaylistItem/p8>
Etc. Etc. Etc.

似乎问题出在删除规则上。投诉是“缺少删除传播”,因此 nullify 似乎是错误的选择。但是,为什么错了?这对我来说没有意义。 Apple's Core Data Programming Guide 中的级联删除规则的措辞使得如果我将播放列表项的删除规则设置为级联,我似乎要删除视频和播放列表对象。

级联 - 删除关系目的地的对象

此外,如果我在快速枚举循环中将播放列表项与视频和播放列表的关系设置为 nil,Core Data 不会抱怨必须修复丢失的删除传播。

for (FHPlaylistItem *pi in *playlistItems) {
    [pi setVideo:nil];
    [pi setPlaylist:nil];
    [context deleteObject:pi];
}

编辑:不,手动消除关系并非在所有情况下都有效。 (也许并不奇怪?)

【问题讨论】:

标签: core-data ios5


【解决方案1】:

在 Playlist 实体上,我没有暴露 playlistItem 关系/集。相反,我有一个名为“videos”的临时未定义属性,它是通过对播放列表项集进行排序生成的视频数组。

也许这就是问题所在。不清楚您如何将关系命名为Video。如果关系和瞬态属性都被命名为videos,你肯定会遇到问题。为什么不在Playlist 的h 文件中正常声明videos 关系,除了(而不是代替)您对videosSorted(瞬态数组)的声明。

另外,请确保在模型中明确哪些关系是彼此相反的。

【讨论】:

  • 播放列表与视频之间没有关系。视频数组是从播放列表到播放列表项的关系生成的。我已经更改了措辞以使其更清楚。
【解决方案2】:

如果在你的删除块之后尝试 [[self managedObjectContext] processPendingChanges] 将为你解决奇怪的消息。

当您在同一个运行循环周期中继续更改托管对象上下文并且某些涉及的对象与已删除对象有关系时,Core Data 似乎会在某些情况下感到困惑。

问候,

斯文。

【讨论】:

  • 我刚刚在自己的代码中遇到了这个问题。在对象删除后调用 -processingPendingChanges 使 Core Data 安静。
  • 我也面临同样的问题。但是添加上述方法后没有变化,问题仍然存在:stackoverflow.com/questions/49129364/…
【解决方案3】:

-processPendingChanges 对我不起作用。起作用的是在我的 NSManagedObject 子类中实现 -prepareForDeletion 并从有问题的一对多关系中手动删除要删除的对象:

- (void)prepareForDeletion {
    [[[self owningEntity] mutableSetValueForKey:@"ownedEntities"] removeObject:self];
}

我已经对我的数据模型进行了三次检查,看起来还不错。我不知道为什么会产生这个错误。但这似乎至少让它消失了。

【讨论】:

    【解决方案4】:

    使用 performBlock 为我修复了它:

    [context performBlock:^{
    
    // delete objects
    
    // save context
    
    }];
    

    【讨论】:

      猜你喜欢
      • 2011-10-04
      • 2012-03-31
      • 1970-01-01
      • 1970-01-01
      • 2012-04-28
      • 1970-01-01
      • 2011-01-20
      • 2011-09-29
      • 1970-01-01
      相关资源
      最近更新 更多