Сохранение NSManagedObjectContext с исчезновением ячеек UITableView - PullRequest
0 голосов
/ 24 февраля 2011

У меня возникла следующая проблема.

Я пишу программу для чтения RSS, используя в качестве руководства пример CoreData и Apple Recipes.У меня есть кнопка обновления, которая повторно загружает RSS и проверяет, используя NSFetchRequest, если есть новые данные.Как только я закончу работу с элементами, я фиксирую изменения с помощью метода сохранения NSManagedObjectContext.

После сохранения контекста tableView исчезнет!

Затем я решил вызвать reloadData для tableView, чтобы отразитьизменения.Итак, после сохранения NSManagedObjectContext я вызываю:

[self performSelectorOnMainThread:@selector(updateTableItems) withObject:nil waitUntilDone:NO];

-(void) updateTableItems {
    [self.tableView reloadData];
}

Это действие заставляет ячейку удалять данные во время прокрутки, когда я открываю представление и возвращаюсь, я вижу все изменения и все в порядке.

Я также прочитал в одном из потоков, что мне следует использовать NSFetchedResultsController и убедиться, что UITableView является делегатом, такой же проблемой, как и предыдущий.

Что я делаю неправильно?Почему я не вижу изменений на месте?Почему содержимое ячейки удаляется?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 23 февраля 2012

У меня была похожая проблема, и это сводило меня с ума. В основном в моем коде есть множество конкурирующих потоков, пытающихся обновить одни и те же данные в одно и то же время (данные за табличным представлением), и я думаю, что это как-то заставляет UITableView «взорваться», и его методы делегата перестают работать. (Вы можете доказать это, добавив NSLog в методы делегата).

Это происходит совершенно случайно и очень трудно воспроизвести.

Я пытался исправить это всеми возможными способами, но единственное, что, по-видимому, надежно гарантирует, что этого не произойдет, - это полное воссоздание моего UITableView при каждом изменении данных, как показано ниже. (Так что в основном меняйте везде, где вы вызываете [self.tableView reloadData] со следующим)

// The UITableView may in rare circumstances all of a sudden failed to render 
// correctly. We're not entirely sure why this happens but its something to 
// do with multiple threads executing and updating the data behind the view 
// which somehow causes the events to stop firing.  Resetting the delegate and 
// dataSource to self isn't enough to fix things however so we have to 
// completely recreate the UITableView and replace the existing one.

UITableView* tempTableView = [[[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 387)] autorelease];
tempTableView.separatorColor = [UIColor grayColor];
tempTableView.backgroundColor = [UIColor clearColor];

if (self.tableView != nil)
{
    [tempTableView setContentOffset:self.tableView.contentOffset animated:NO];
}

tempTableView.delegate = self;
tempTableView.dataSource = self;
[tempTableView reloadData];  

 if (self.tableView != nil) {
     [self.tableView removeFromSuperview];
     self.tableView = nil;
 }

 [self.view addSubview:tempTableView];
 self.tableView = tempTableView;

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

0 голосов
/ 25 февраля 2011

Похоже, вы используете два или более контекста в отдельных потоках.Вы фиксируете сохранение в контексте фонового потока, но не объединяете изменения с контекстом, связанным с пользовательским интерфейсом в переднем потоке.Это приводит к тому, что контекст пользовательского интерфейса не синхронизируется с хранилищем, что приводит к исчезновению строк таблицы при прокрутке.

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

Чтобы избежать этой проблемы, сразу после сохранения фонового контекста вызовите refreshObject:mergeChanges: в переднем контексте.Имейте передний контекстный регистр для NSManagedObjectContextDidSaveNotification из фонового контекста

...