NSOperationQueue и NSFetchedResultsController

#core-data #nsoperation #nsoperationqueue

#основные данные #nsoperation #nsoperationqueue

Вопрос:

я использую комбинацию queue и resultscontroller для обновления и отображения некоторых объектов coredata.

в моем uitableviewcontroller я вызываю каждые X секунд метод в моем главном объекте контроллера.

 [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(test:)            userInfo:nil repeats:YES];

}

- (void)test:(NSTimer*)theTimer {

[[MainController instance] updatePersons];

}
  

В этом методе пользовательский объект NSOperation будет добавлен к моему основному Q.

 - (BOOL)updatePersons {

UpdatePersonsOperation* u = [[UpdatePersonsOperation alloc] init];
[u setQueuePriority:NSOperationQueuePriorityVeryHigh];

[operationQ u];

[u release];
  

Сама операция создает новый managedobjectcontext и пытается загрузить некоторый xml из Интернета и пытается обновить базу данных coredata… (Этот код работает!)

В моем главном контроллере я получаю сообщение об изменении контекста и использую mergeChangesFromContextDidSaveNotification для объединения и обновления контекста моего основного объекта. Все resultscontroller используют этот контекст основного объекта.

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationManagedObjectContextDidSave:) name:
                                        NSManagedObjectContextDidSaveNotification object:nil];
  

На самом деле все работает, но когда я вставляю новый объект внутри NSOperation, требуется 4-6 секунд, пока пользовательский интерфейс не обновится и не отобразит этот новый объект… Кроме того, пользовательский интерфейс блокируется… Невозможно прокрутить или запустить другое взаимодействие…

Когда я не использую очередь и помещаю свой код для загрузки и обновления объектов в метод внутри моего класса uitableviewcontroller, и я использую это

 [NSThread detachNewThreadSelector:@selector(codeFromUpdatePersonsOperation) toTarget:self withObject:nil];
  

Все работает очень хорошо, без каких-либо задержек или зависания пользовательского интерфейса…

Кто-нибудь может объяснить мне это поведение?

Спасибо

Комментарии:

1. После долгих исследований возникла проблема с NSFetchedResultsController! Мой совет никогда не используйте NSFetchedResultsController при обновлении и загрузке сложных данных из Интернета. Реализуйте свою собственную логику обновления для uitableview.

Ответ №1:

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

 [target performSelectorOnMainThread:@selector(methodToUpdateUI:) withObject:dataFromRetrievalOperation waitUntilDone:NO];
  

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