asihttprequest вылетает мое приложение - PullRequest
9 голосов
/ 18 апреля 2011

У меня есть приложение на основе навигации. Нажмите кнопку на главном экране, затем я добавлю новый вид на контроллер навигации. Все довольно простые вещи.

Когда загружается новое представление, я выполняю запрос ASIHTTPRequest для получения некоторых данных JSON, представляющих собой список URL-адресов изображений. Затем я делаю цикл for, создаю кучу запросов ASIHTTP, добавляю их в очередь и затем запускаю очередь.

Но если я нажму на кнопку «Назад» до завершения очереди, приложение вылетает, это приложение отображает дома и позволяет сказать, что вы выбрали неправильный дом, очень быстро нажмите назад, прежде чем отобразится какая-либо фотография, аварийный сбой.

Этот поток http://groups.google.com/group/asihttprequest/browse_thread/thread/3d4815198aa889b9 очень хорошо объясняет мою проблему, за исключением того, что я отменяю все запросы на просмотр, которые выгрузились, устанавливаю делегат равным nil и освобождаю очередь.

Тем не менее я терплю крах. Каждый раз, когда я пользуюсь 3G, у меня почти всегда происходит сбой, но на Wi-Fi очень сложно его сделать, но вполне выполнимо.

Почти в 80% случаев отладчик переходит на эту строку в ASIHTTPRequest.m

(void)requestReceivedResponseHeaders:(NSMutableDictionary *)newResponseHeaders { 
  if ([self error] || [self mainRequest]) { return; }  
--> if (delegate && [delegate respondsToSelector:didReceiveResponseHeadersSelector]) {

Во многих случаях к нему переходят:

(void)requestReceivedResponseHeaders:(NSMutableDictionary *)newResponseHeaders { 
  if ([self error] || [self mainRequest]) { return; }    
---> if (delegate && [delegate respondsToSelector:didReceiveResponseHeadersSelector]) {  

Объявление в нескольких случаях попадает в мой основной цикл

int main(int argc, char *argv[]) {  
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
--> int retVal = UIApplicationMain(argc, argv, nil, nil); with SIGBART error [pool release]; return retVal;  

Я использую MBP и MacPro, последнюю версию OS X, Xcode 4.0.2 и тестирую на всех устройствах Apple, кроме оригинальных iPhone.

Я действительно не хочу переписывать все мое приложение, но есть ли что-нибудь еще, что можно сравнить с ASIHTTPRequest?

Ответы [ 4 ]

12 голосов
/ 18 апреля 2011

Попробуйте отменить и отменить делегат в -viewWillUnload, а не -viewDidUnload.Я подозреваю, что окно времени, в которое оно фактически выгружается (между вызовами этих двух методов UIViewController), является периодом времени, когда вы можете быть разрушаемыми.Делегат исчез, но вы еще не сообщили объекту ASIHTTPRequest.

4 голосов
/ 03 февраля 2012

Ошибка в том, что делегат все еще установлен.

Я нашел 2 способа исправить это.

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

Лучший способ - не устанавливать делегат и не использовать "setDidFinishSelector", а вместо этого использовать "setCompletionBlock: ^". Это будет работать только на устройствах с iOS 4.0 и выше, что составляет более 90-95% и продолжает расти. Это просто отличный способ, который не приведет к сбою приложения.

3 голосов
/ 18 апреля 2011

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

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

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

Вариант 2

Другим подходом может быть отключение навигации пользователя до завершения работы сети. Поместите модальное представление на весь экран, который показывает представление uiactivity, чтобы пользователь знал, что его действия блокируются. Затем вы можете отключить модальное представление, когда данные поступят. Если вы красиво оформите экран с градиентом, чтобы фон немного потускнел, это может выглядеть хорошо. Но на самом деле это не лучший подход - вместо этого вы должны исправить делегата AWOL.

Возможно, нам понадобится больше кода, касающегося создания, уничтожения очереди и т. Д., Чтобы найти точную проблему.

1 голос
/ 18 апреля 2011

Ваш делегат приложения может иметь массив очередей запросов. Массив живет независимо от состояния стека контроллера навигации и связанных представлений. Вместо того чтобы связывать запросы с контроллером представления в стеке навигации и выполнять трюки пользовательского интерфейса, чтобы заблокировать возврат к родительскому представлению, вы можете добавить запросы к экземпляру очереди делегата приложения или остановить все запросы и очистить очередь и т. Д.

...