При переключении вида на панели навигации, как безопасно завершить поток NSOperationQueue без ошибки EXC_BAD_ACCESS
-
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];