У меня есть простая таблица UIViewTable с детализацией детализации, реализованной с помощью push-перехода UINavigationController в раскадровке.Время от времени случается так, что контроллер табличного представления, кажется, освобождается, в то время как я нахожусь в подробном представлении, поэтому я получаю известное:
[MyViewController controllerWillChangeContent:]: message sent to deallocated instance
Я объясняю лучше, у меня есть очередь NSOperation, котораязагрузить мои данные асинхронно и заполнить таблицу, как только она только что закончилась.Данные правильно получены и таблица заполнена.Для подробного просмотра я нажимаю на ячейку и передаю NSManagedObjectID в контроллер назначения в методе prepareForSegue.Очень случайно, когда я вносил изменения в детальный вид, извлеченный контроллер терял свой делегат или, как кажется, сам делегат, который является контроллером, освобождается.Вызывает сбой.
Выбранный контроллер результатов объявляется как свойство:
@property(nonatomic,strong) NSFetchedResultsController *fetchedResultsController;
Тогда вот как все работает, начиная с viewDidLoad.
- (void)viewDidLoad {
[super viewDidLoad];
[self loadDataAsynchronously];
}
-(void)loadDataAsynchronously {
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(loadData)
object:nil];
[queue addOperation:operation];
}
-(void)loadData {
NSFetchRequest *findAllEntities = [[NSFetchRequest alloc] init];
[findAllEntities setEntity:ENTITY_DESC];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"created" ascending:YES];
[findAllEntities setSortDescriptors:[NSArray arrayWithObject:sort]];
[findAllEntities setFetchBatchSize:20];
[NSFetchedResultsController deleteCacheWithName:@"MyCache"];
if(self.fetchedResultsController==nil) {
self.fetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:findAllPlants
managedObjectContext:MOC
sectionNameKeyPath:nil
cacheName:@"MyCache"];
self.fetchedResultsController.delegate=self;
}
NSError *error=nil;
if (![FRC performFetch:&error]) {
exit(EXIT_FAILURE);
}
[self.dataTableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
}
thisкод работает, и большую часть времени также работает в подробном представлении, которое называется следующим образом:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
IP2SegueIdentifier segueIdentifier = [IP2Factory segueSolver:[segue identifier]];
MyDestinationViewController *dvc = [segue destinationViewController];
NSIndexPath *indexPath = [TV indexPathForSelectedRow];
dvc.entityID=[[self.fetchedResultsController objectAtIndexPath: indexPath] objectID];
}
и целевой контроллер правильно получает идентификатор объекта и восстанавливает объект, запрашивая контекст.Затем, когда я нахожусь в контроллере подробного представления, я могу внести изменения в сущность, а когда я вернусь к иерархии навигации, я сохраню контекст.Именно в этот момент происходит сбой приложения, прямо при сохранении контекста.Не так часто, но время от времени.Поскольку извлеченный контроллер результатов распознает изменение и передал его делегату, который уже освобожден.
У меня мало сомнений на этом этапе, я использую iOS 5 и ARC, так что компилятор должен иметь (почти) полныйконтроль над методами освобождения и освобождения.И я также использую раскадровку с простой иерархией навигации, которая должна гарантировать, что вся предыдущая цепочка контроллеров представления будет сохранена.
Я также запустил профилировщик для анализа утечек памяти / зомби, но не смогВыясни, что что-то не так, наоборот, я был рад, что все управление объектами было в порядке.
У меня пока мало кто догадывается, поэтому, пожалуйста, не стесняйтесь указывать на то, что я мог забыть проверить или что-товы видите неправильно в моем коде.
спасибо