При переключении вида на панели навигации, как безопасно выйти из потока NSOperationQueue без ошибки EXC_BAD_ACCESS - PullRequest
0 голосов
/ 05 января 2010

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

Если я нажму кнопку «Назад» на панели навигации, чтобы переключиться из UITableView в другое представление после загрузки всех сообщений, все будет в порядке. Но, если я нажимаю кнопку «Назад», когда какое-то сообщение все еще загружается, EXC_BAD_ACCESS бросается. Я проверил, что исключение произошло, когда настроенный контроллер NSOperation уведомляет контроллер UITableView с помощью метода performSelectorOnMainThread. Звук как целевой контроллер UITableView не является недействительным после переключения представления, но я думаю, что Navigation 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];
    }
}

Ответы [ 2 ]

0 голосов
/ 05 января 2010

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

Я рекомендую поместить ваш экземпляр NSOperationQueue *myQueue в ваш делегат приложения.

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

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

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

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

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

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

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

[[UIAppDelegate myQueue] addOperation:myOperation];
0 голосов
/ 05 января 2010

Вы пытались вызвать [operationQueue cancelAllOperations] в вашем viewWillDisappear методе?

...