При переключении вида на панели навигации, как безопасно завершить поток NSOperationQueue без ошибки EXC_BAD_ACCESS

StackOverflow https://stackoverflow.com/questions/2003445

  •  18-09-2019
  •  | 
  •  

Вопрос

Я использую UITableView для отображения некоторых строковых сообщений, и я использую NSOperationQueue для хранения настроенной NSOperation, которая извлекает сообщение в фоновом потоке.После успешной выборки одного сообщения настроенная NSOperation уведомит контроллер UITableView о его отображении.

Если я нажму кнопку "Назад" на панели навигации, чтобы переключиться с UITableView на другой вид после загрузки всех сообщений, все будет в порядке.Но, если я нажимаю кнопку "Назад", пока какое-то сообщение все еще загружается, выдается EXC_BAD_ACCESS .Я проверил, что исключение произошло при настройке NSOperation notify UITableView controller с помощью performSelectorOnMainThread способ.Похоже, что целевой контроллер UITableView не является недействительным после переключения вида, но я думаю, что навигационный контроллер будет содержать экземпляр view controller.Могу я узнать, как решить эту проблему?Спасибо.

Настроенная операция инициализируется в контроллере UITableView следующим кодом:

StatusMessageLoadingOperation *operation = [[StatusMessageLoadingOperation alloc] 
                                            initWithData:person
                                            messageArray:cachedStatusMessages
                                            target:self 
                                            action:@selector(didFinishStatusMessages:)];
[operationQueue addOperation:operation];
[operation release];

Настроенный класс NSOperation обновит UITableView следующим кодом:

- (void)main{
    for (int i = 0; i < [[person statusMessages] count]; i++) {
        [target performSelectorOnMainThread:action withObject:messageArray waitUntilDone:NO];
    }
}
Это было полезно?

Решение

Ты пробовал звонить [operationQueue cancelAllOperations] в вашем viewWillDisappear способ?

Другие советы

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

Моя рекомендация состоит в том, чтобы поместить ваш NSOperationQueue *myQueue создайте экземпляр в вашем делегате приложения.

Используйте делегат приложения -applicationDidFinishLaunching: и -dealloc методы для инициализации и освобождения вашей очереди и ее содержимого.

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

Чтобы упростить доступ к вашей очереди, настройте следующее определение макроса:

#define UIAppDelegate ((MyAppDelegate *)[UIApplication sharedApplication].delegate)

Затем вы можете использовать макрос для доступа к вашей очереди следующим образом, например:

NSLog(@"%@", [[UIAppDelegate myQueue] operations]);

Или, например:

[[UIAppDelegate myQueue] addOperation:myOperation];
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top