Ваша обработка NSFetchedResultsController испорчена.Сначала рассмотрим этот код:
NSFetchedResultsController *aFRC = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
aFRC.delegate = self;
self.fetchedResultsController = aFRC;
Если ваше свойство fetchedResultsController
объявлено assign
, этот код более или менее правильный (хотя тогда семантика неверна).Если свойство объявлено retain
, то здесь вы указываете ссылку aFRC
.
Но в любом случае ваше освобождение неверно.В dealloc у вас есть это:
self.fetchedResultsController = nil;
[_fetchedResultsController release];
Первая строка устанавливает для свойства (и это, вероятно, _fetchedResultsController
ivar) значение nil, поэтому вторая строка никогда не может освободить объект.Если свойство объявлено retain
, я думаю, это попытка устранить утечку, упомянутую выше;если он объявлен assign
, это свидетельствует о неверной семантике, упомянутой выше.И даже если это работало «правильно», версия в viewDidUnload
не имеет такого дополнительного выпуска, поэтому все еще неправильный.
В любом случае, утечка ссылки оставляет NSFetchedResultsController живым,В конце концов он находит изменение, которое пытается отправить своему делегату.И это, конечно, не получается, потому что делегат уже давно освобожден.
Скорее всего, вам никогда не потребуется назначать fetchedResultsController извне реализации этого класса.Тогда вы действительно должны сделать что-то вроде этого:
Свойство fetchedResultsController
должно быть объявлено как:
@property (retain, readonly) NSFetchedResultsController *fetchedResultsController;
С существующим fetchedResultsController
все в порядке, за исключением того, что ему следует назначить_fetchedResultsController
ivar напрямую вместо попытки присвоения self.fetchedResultsController
.
Тогда каждый из методов dealloc и viewDidUnload должен освобождать объект примерно так:
[_fetchedResultsController release];
_fetchedResultsController = nil;
Вы также можете установить _fetchedResultsController.delegate
nil перед его выпуском, чтобы быть уверенным, но документация не указывает, что это необходимо, как это делается для некоторых других классов.