Невозможно изменить порядок отношения NSOrderedSet в Базовых данных - PullRequest
9 голосов
/ 28 февраля 2012

Кто-нибудь знает, почему я не могу сохранить изменение порядка объектов в отношении NSOrderedSet в Core Data? Я уже знаю об ошибке, когда использование сгенерированных функций для отношения NSOrderedSet не работает должным образом, и поэтому я всегда использую keypath. Ниже приведен код для двух функций в виде таблицы.

tableView:moveRowAtIndexPath:toIndexPath: утверждает, что успешно сохранил, но изменение на самом деле не сохраняется, то есть, если я выполню [tableView reloadData];, старый порядок все еще там. Даже если я выйду из приложения и перезапущу его, порядок не изменился. Я уточнил это с несколькими NSLogs. Вторая функция, tableView:commitEditingStyle:forRowAtIndexPath:, которую я использую для удаления записи NSOrderedSet, работает отлично.

Моя теория состоит в том, что Core Data отбрасывает информацию о заказе из отношения NSOrderedSet во внутреннем представлении, и поэтому, поскольку объекты остаются неизменными, он полагает, что ему не нужно ничего сохранять. Кто-нибудь испытывал что-то подобное раньше? Если так, вы нашли обходной путь?

-(void) tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath 
{

    NSManagedObjectContext *context= [self managedObjectContext];

    Playlist *playlist = (Playlist*) [context objectWithID:playlistID];


    [playlist willChangeValueForKey:@"tracks"];
    NSMutableOrderedSet *exchange = [playlist mutableOrderedSetValueForKey:@"tracks"];;

    NSInteger fromIndex = sourceIndexPath.row;
    NSInteger toIndex = destinationIndexPath.row;

    NSMutableArray *arrayOfTracks = [NSMutableArray arrayWithArray:[exchange array]];

    [arrayOfTracks exchangeObjectAtIndex:fromIndex withObjectAtIndex:toIndex];
    [[playlist mutableOrderedSetValueForKey:@"tracks"] removeAllObjects];


    [[playlist mutableOrderedSetValueForKey:@"tracks"] addObjectsFromArray:arrayOfTracks];
    playlist.md5Hash = nil;
    [playlist didChangeValueForKey:@"tracks"];

    NSError *savingError = nil;
    if ([context save:&savingError]){
        NSLog(@"Successfully saved the context for reorder"); 
    } else {
        NSLog(@"Failed to save the context. Error = %@", savingError); }

}


- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        NSManagedObjectContext *context= [self managedObjectContext];

        Playlist *playlist = (Playlist*) [context objectWithID:playlistID];

        Track *track = [self.tracksFRC objectAtIndexPath:indexPath];    


        NSMutableOrderedSet *exchange = [NSMutableOrderedSet orderedSetWithOrderedSet: playlist.tracks];


        [exchange removeObject:track];
        [track removeBelongingPlaylistObject:playlist];
        NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [playlist.tracks count])];

        [[playlist mutableOrderedSetValueForKey:@"tracks"] replaceObjectsAtIndexes:indexSet withObjects:[exchange array]];

        playlist.md5Hash = nil;

        NSError *savingError = nil;
        if ([context save:&savingError]){
            NSLog(@"Successfully saved the context for remove entry"); 
        } else {
            NSLog(@"Failed to save the context. Error = %@", savingError); }
    }
}

РЕДАКТИРОВАТЬ: Мне удалось решить эту проблему, дважды вызвав [context save:&savingError], один раз с удаленными записями и один раз с их повторной вставкой в ​​новом порядке. Это исправление не должно быть необходимым, хотя.

Ответы [ 2 ]

9 голосов
/ 28 ноября 2012

В чем причина преобразования в массив?NSMutableOrderedSet уже поддерживает метод exchangeObjectAtIndex:withObjectAtIndex:

Я бы посоветовал:

NSMutableOrderedSet *exchange = [playlist.tracks mutableCopy];

NSInteger fromIndex = sourceIndexPath.row;
NSInteger toIndex = destinationIndexPath.row;

[exchange exchangeObjectAtIndex:fromIndex withObjectAtIndex:toIndex];

playlist.tracks = exchange;

Кроме того, у вас, похоже, много-много взаимосвязей между списком воспроизведения и дорожкой, поэтому ваш метод удаленияработает из-за вашего вызова [track removeBelongingPlaylistObject:playlist]; Все остальное в методе должно быть избыточным (кроме сохранения контекста).

2 голосов
/ 20 июля 2015

Преобразование кода @ ikuramedia в swift дает:

var exchange: NSMutableOrderedSet = playlist.tracks.mutableCopy() as! NSMutableOrderedSet

exchange.exchangeObjectAtIndex(fromIndexPath.row, withObjectAtIndex: toIndexPath.row)

playlist.tracks = exchange

На случай, если кому-то это нужно

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