2

У меня есть подкласс NSOperation, который выполняет операции асинхронного действия с UITableView.Отменено NSOperation EXC_BAD_ACCESS сбой при настройке isFinished

Я отменяю правильные методы начать и закончить так:

- (void)start 
{ 
    [self willChangeValueForKey:@"isExecuting"]; 
    self.isExecuting = YES; 
    [self didChangeValueForKey:@"isExecuting"]; 

    if (self.isCancelled) 
    { 
     [self finish]; 
     return; 
    } 
} 
- (void)finish 
{ 
     if (!_isExecuting) 
     { 
      [self willChangeValueForKey:@"isExecuting"]; 
      _isExecuting = YES; 
      [self didChangeValueForKey:@"isExecuting"]; 
     } 

     [self willChangeValueForKey:@"isExecuting"]; 
     [self willChangeValueForKey:@"isFinished"]; 

     _isExecuting = NO; 
     _isFinished = YES; 

     [self didChangeValueForKey:@"isExecuting"]; 
     [self didChangeValueForKey:@"isFinished"]; 
} 

У меня есть проблема, это если я прокрутить таблицу и удалить строку, это вызывает cancel метод на операции, однако, как операции постепенно завершаются, и он идет дальше по таблице, он падает с ошибкой EXC_BAD_ACCESS на линии [self didChangeValueForKey:@"isFinished"];

Код довольно сложный, чтобы вставить все это здесь, но я хотел бы знать, как я могу отслеживать вниз, какой объект вызывает сообщение KVO?

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

Если я обертываю методы KVO в try/catch, он никогда не попадает и все еще падает.

Я попытался переопределение методов КВО в моем NSOperation подкласса, но они никогда не называют:

- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context 
{ 
    NSLog(@"%s - %@", __PRETTY_FUNCTION__, observer); 
    [super addObserver:observer forKeyPath:keyPath options:options context:context]; 
} 

Можно ли видеть, кто наблюдатели?

+0

Вы нашли ответ на эту проблему, не помните? –

ответ

2

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

  1. В start не должно быть self.isExecuting = YES_isExecuting = YES;?
  2. Добавьте объект под названием identifier типа NSString и установите его для каждого op.
  3. Добавить метод dealloc и зарегистрировать identifier.
  4. В finish тест на isCancelled и немедленно вернуться, если это так.

Другая мысль состоит в том, чтобы дважды сохранить операции - поместить их в NSDictionary с identifier в качестве ключа и посмотреть, что-либо изменится.

+0

1, спасибо изменено. 2 и 3 Я использовал 'indexPath' и удалил indexPath 4-14, который отменил и отменил' NSOperation' немедленно. Сразу после окончания очереди операции indexPath 4-9 он разбился. Из моего понимания документов Apple, даже отмененные операции начинаются, а затем заканчиваются. Так что, должно быть, нужно начинать 4-14, но так как это было dealloc'd, я не вижу, как он может упасть на метод финиша. – Darren

+0

Его долгое время я использовал NSOperations - я переключился на GCD, как только он вышел. Почему вы не попробовали 4? Возможно, вы пытаетесь изменить свойства после отмены, вызывают проблемы ... –

+0

Я думаю, что исправил его, и это связано с 4. В моем методе отмены я вручную вызывал законченный метод. Я уверен, что я где-то читал это, потому что метод отмены просто перебрасывает 'isCancelled' bool. Удаление, похоже, остановило крушение – Darren