Правило удаления отношения Core Data - Nullify + Cascade - PullRequest
5 голосов
/ 01 апреля 2012

Объекты:

  • Видео
  • Элемент списка воспроизведения
  • Список воспроизведения

Отношения:

  • Видео необязательно для многих элементов списка воспроизведения, и правило удаления имеет значение
  • Список воспроизведения имеет значение ко многим, по меньшей мере, для одного элемента списка воспроизведения, а правило удаления имеет значение
  • Элемент списка воспроизведения требуется дляодин для видео, и правило удаления имеет значение nullify
  • Элемент списка воспроизведения требуется to-one для списка воспроизведения, а правило удаления имеет значение nullify

В объекте списка воспроизведения я не отображал playlistItemотношения / набор.Вместо этого у меня есть временный неопределенный атрибут, называемый «видео», который представляет собой массив сущностей Видео, сгенерированных путем сортировки набора элементов списка воспроизведения.Между объектами Playlist и Video нет взаимосвязи.

У меня проблемы при сохранении измененного экземпляра Playlist в контексте управляемого объекта.

Из 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 сохраняет просто отлично.Тем не менее, последующие изменения атрибута videos приводят к появлению 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.

Кажется, проблема в правиле удаления.Жалоба связана с «отсутствующим распространением удаления», так что кажется, что аннулирование - неправильный выбор.Но почему это не так?Это не имеет смысла для меня.Формулировка правила каскадного удаления в Руководстве по программированию основных данных Apple создает впечатление, что я собираюсь удалить объекты Video и Playlist, если я установил правило удаления элемента списка воспроизведения в каскад.

Каскад - удаление объектов в месте назначения взаимосвязи

Кроме того, если я установлю связь между элементом списка воспроизведения и видео и списком воспроизведения равным нулю в цикле быстрого перечисления, Core Dataне жалуется на необходимость исправления отсутствующего распространения удаления.

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

РЕДАКТИРОВАТЬ: Нет, обнуление отношений вручную не работает во всех ситуациях.(Может быть, не удивительно?)

Ответы [ 4 ]

10 голосов
/ 14 апреля 2012

Попробуйте, если [[selfagedObjectContext] processPendingChanges] после вашего блока удаления решит странные для вас сообщения.

Кажется, что в некоторых ситуациях Базовые данные будут сбиваться с толку, когда вы продолжаете изменять контекст управляемого объекта в одном и том же цикле цикла выполнения, и некоторые из задействованных объектов имели отношения к удаленным объектам.

С уважением,

Свен.

1 голос
/ 01 сентября 2013

-processPendingChanges не работает для меня.Что помогло, так это реализовать -prepareForDeletion в моем подклассе NSManagedObject и вручную удалить объект, который нужно удалить, из проблемного отношения ко многим:

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

Я трижды проверил свою модель данныхи выглядит нормально.Я не знаю, почему эта ошибка возникает.Но это, кажется, заставляет его исчезнуть, по крайней мере.

0 голосов
/ 28 января 2016

с помощью executeBlock исправили это для меня:

[context performBlock:^{

// delete objects

// save context

}];
0 голосов
/ 02 апреля 2012

В объекте Playlist я не раскрыл отношение / набор playlistItem. Вместо этого у меня есть временный неопределенный атрибут, называемый «видео», который представляет собой массив видео, созданный путем сортировки набора элементов списка воспроизведения.

Может быть, в этом проблема. Непонятно, как вы назвали отношение к Video. Если и отношение, и временный атрибут имеют имя videos, у вас наверняка возникнет проблема. Почему бы не объявить отношение videos обычно в h-файле Playlist, в дополнение к (а не вместо) вашему объявлению, скажем, для videosSorted (переходный массив).

Кроме того, убедитесь, что в модели ясно, какие отношения обратны друг другу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...