Итак, потратив некоторое время на эту проблему ...!
Приведенные выше ответы - отличные строительные блоки, и без них я бы потерялся, но, как и в случае с другими респондентами, я обнаружил, что они работают лишь частично. Если вы их реализуете, вы обнаружите, что они срабатывают один или два раза, а затем ошибка или вы потеряете данные по мере продвижения. Ответ ниже далек от совершенства - это результат довольно долгих ночей, проб и ошибок.
У этих подходов есть некоторые проблемы:
NSFetchedResultsController, связанный с NSMutableArray, не гарантирует, что контекст будет обновлен, поэтому вы можете видеть, что иногда это работает, но не работает в других случаях.
Подход «копирование и удаление» для обмена объектами также сложно предсказать. В другом месте я нашел ссылки на непредсказуемое поведение при обращении к объекту, который был удален в контексте.
Если вы используете строку индекса объекта и имеете разделы, это не будет работать должным образом. Некоторые из приведенных выше кодов используют только свойство .row, и, к сожалению, это может относиться к более чем одной строке в yt.
Использование NSFetchedResults Delegate = nil подходит для простых приложений, но учтите, что вы хотите использовать делегат для захвата изменений, которые будут реплицированы в базу данных, тогда вы увидите, что это не будет работать должным образом.
Core Data на самом деле не поддерживает сортировку и упорядочение, как это делает правильная база данных SQL. Вышеупомянутое решение для цикла for хорошо, но действительно должен быть правильный способ упорядочивания данных - IOS8? - поэтому вам нужно вникнуть в это, ожидая, что ваши данные будут повсюду.
Проблемы, которые люди опубликовали в ответ на эти сообщения, связаны со многими из этих проблем.
У меня есть простое табличное приложение с разделами для «частичной» работы - я все еще работаю над необъяснимым поведением пользовательского интерфейса, но я считаю, что дошел до сути ...
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
Это обычный делегат
{
userDrivenDataModelChange = YES;
использует механизм семафоров, как описано выше, со структурами возврата if ().
NSInteger sourceRow = sourceIndexPath.row;
NSInteger sourceSection = sourceIndexPath.section;
NSInteger destinationRow = destinationIndexPath.row;
NSInteger destinationSection = destinationIndexPath.section;
Не все они используются в коде, но полезно иметь их для отладки.
NSError *error = nil;
NSIndexPath *destinationDummy;
int i = 0;
Окончательная инициализация переменных
destinationDummy = [NSIndexPath indexPathForRow:0 inSection:destinationSection] ;
// there should always be a row zero in every section - although it's not shown
Я использую строку 0 в каждом скрытом разделе, в котором хранится имя раздела. Это позволяет видеть раздел, даже если в нем нет «живых» записей. Я использую строку 0, чтобы получить имя раздела. Код здесь немного неаккуратный, но он выполняет свою работу.
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
NSManagedObject *currentObject = [self.fetchedResultsController objectAtIndexPath:sourceIndexPath];
NSManagedObject *targetObject = [self.fetchedResultsController objectAtIndexPath:destinationDummy];
Получить контекст, а также исходные и целевые объекты
Затем этот код создает новый объект, который берет данные из источника, а раздел - из места назначения.
// set up a new object to be a copy of the old one
NSManagedObject *newObject = [NSEntityDescription
insertNewObjectForEntityForName:@"List"
inManagedObjectContext:context];
NSString *destinationSectionText = [[targetObject valueForKey:@"section"] description];
[newObject setValue:destinationSectionText forKeyPath:@"section"];
[newObject setValue: [NSNumber numberWithInt:9999999] forKey:@"rowIndex"];
NSString *currentItem = [[currentObject valueForKey:@"item"] description];
[newObject setValue:currentItem forKeyPath:@"item"];
NSNumber *currentQuantity =[currentObject valueForKey:@"quantity"] ;
[newObject setValue: currentQuantity forKey:@"rowIndex"];
Теперь создайте новый объект и сохраните контекст - это обман операции перемещения - вы можете не получить новую запись точно в том месте, где она была отброшена - но, по крайней мере, она будет в нужном разделе.
// create a copy of the object for the new location
[context insertObject:newObject];
[context deleteObject:currentObject];
if (![context save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
Теперь выполните обновление цикла for, как описано выше. Обратите внимание, что контекст сохраняется до того, как я это сделаю - понятия не имею, зачем это нужно, но он не работал должным образом, когда этого не было!
i = 0;
for (NSManagedObject *mo in [self.fetchedResultsController fetchedObjects] )
{
[mo setValue:[NSNumber numberWithInt:i++] forKey:@"rowIndex"];
}
if (![context save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
Установите семафор обратно и обновите таблицу
userDrivenDataModelChange = NO;
[tableView reloadData];
}
person
user3519965
schedule
10.04.2014