CoreData Merge Изменить странность - PullRequest
1 голос
/ 17 декабря 2011

У меня возникает странная проблема с объектами-зомби, когда я пытаюсь объединить свои изменения с фоновым NSOperation:

(controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:]: message sent to deallocated instance) 

У меня есть ViewController, который выдвигает другие контроллеры на navControllerстек в моем AppDelegate в didSelectRowForIndexPath примерно так:

ABCViewController *myVC = [[ABCViewController alloc] initWithNibName:@"ABCViewController" bundle:nil];

ABCEvent *selectedEvent = [_fetchedResultsController objectAtIndexPath:indexPath];
[myVC setManagedObjectContext:[self managedObjectContext]];
[myVC setTitle:@"Title"];
[myVC setEvent:selectedEvent];

ABCAppDelegate *appDelegate = (ABCAppDelegate *)[[UIApplication sharedApplication] delegate];
[[appDelegate navController] pushViewController:myVC animated:YES];
[myVC release];

Затем в моем ViewDidLoad для ABCViewContoller я создаю очередь операций и добавляю в нее свою фоновую операцию:

_operationQueue = [[NSOperationQueue alloc] init];

А также подключение уведомления, чтобы я мог объединить изменения:

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

Все стандартные вещи, которые я считаю.Проблема в том, что если я выберу строку в главном VC, затем вернусь к ней и снова нажму на строку, я получу следующее сообщение: , отправленное на освобожденный экземпляр message.Теперь, если я отключу уведомление для NSManagedObjectContextDidSaveNotification, то я не получу ошибку, так что это определенно виновник.Мой dealloc во втором контроллере выглядит следующим образом:

- (void)dealloc
{
    [super dealloc];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [_operationQueue release];
}

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

Я довольно озадачен этим.Любая помощь будет высоко ценится.

Ответы [ 2 ]

1 голос
/ 17 декабря 2011

Вы вообще используете fetchedResultsControllerDelegate?

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

0 голосов
/ 17 декабря 2011

Одна быстрая поправка, которая должна помочь, - это [super dealloc], должно всегда быть последним утверждением в вашем dealloc.

Кроме того, поскольку вы выполняете операции CoreData в фоновом потоке (через NSOperationQueue), убедитесь, что вы создаете NSManagedObjectContext для объекта фонового потока в фоновом потоке . Не создавайте его в одном потоке и не назначайте его объекту, который будет работать в другом потоке, иначе у вас возникнут всевозможные проблемы.

Когда вы получаете уведомление NSManagedObjectContextDidSaveNotification, вам необходимо выполнить слияние в том же потоке, к которому относится контекст, с которым вы сливаете в . Скорее всего, это будет ваш главный контекст в (похоже на) делегате вашего приложения, что означает, что он находится в главном потоке.

...