2012-03-06 2 views
3

Приложение составлено из навигационных представлений. Я вызываю функцию в viewDidAppear, котораяiOS, прекратите выполнение функции при нажатии кнопки «назад»

[self extractInfoWithWebsite:[NSString stringWithFormat:@"http://www.cineklik.com/%@-%@.aspx", self.cinemaType, self.location]]; 

Эта функция делает HTML разбора из текущей веб-страницы в Интернете. Код очень долго делится, но идея состоит в том, что он извлекает данные с веб-сайта.

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

Есть ли решение для этого? Спасибо заранее

EDIT:

Я изменил код к следующему: NSOperationQueue * очереди = [NSOperationQueue новый];

/* Create our NSInvocationOperation to call loadDataWithOperation, passing in nil */ 
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self 
                      selector:@selector(extractInfoWithWebsite:) 
                       object:[NSString stringWithFormat:@"http://www.cineklik.com/%@-%@.aspx", self.cinemaType, self.location]]; 

    /* Add the operation to the queue */ 
    [queue addOperation:operation]; 
    [operation release]; 

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

+0

Вы действительно хотите «отменить» запрос? // Другое решение (proces) может заключаться в том, что вы используете что-то вроде bgthread для таких «тяжелых» действий - (при использовании отдельного потока ваш основной не блокируется) – YDL

+0

Если информация загружается , вы должны отключить взаимодействие с пользователем и при завершении включить взаимодействие с пользователем. – HarshIT

+0

Другое решение - отменить загрузку данных при навигации назад – HarshIT

ответ

2

Я хотел бы посмотреть на NSOperation

Стандартный подход внутри NSOperation должен проверить, если они были отменены, прежде чем делать тяжелую обработку.

Here - хорошая ссылка для начала исследования.

EDIT: Я думал, я бы уточнить отмененной части

NSOperations имеют основной() и внутри основной() это хорошая практика, чтобы сделать что-то вроде

NSData* chunkyReply = nil; 

if (!self.isCancelled) { 
    chunkyReply = [NSURL stuff]; 
}  


if (!self.isCancelled) { 
    //parse chunkyReply 
} 
0

Вы можете запустить код загрузки в фоновом режиме, используя:

[self performSelectorInBackground:<#(SEL)#> withObject:<#(id)#>]; 

И тогда вы будете иметь контроль над задней кнопки нажатой, и вы можете захватить его

0

Есть различные виды подходов, то тот, который лучше всего подходит для меня, он инкапсулирует процесс внутри NSOperation, который вы создаете в ViewDidLoad и останавливаетесь в ViewWillDisappear.

Другой подход - создать объект с делегатом, а затем установить делегат nil при выходе из контроллера.

0

Трудно дать вам лучше ответить, не зная точно, что extractInfoWithWebsite: выглядит, но я буду считать, что это разделить на две части:

  • извлекать данные из URL вы передаете его
  • Анализировать, что данные

Для первой части, если вы используете [NSData dataWithContentsOfURL:...] или [NSURLConnection sendSynchronoushRequest:returningResponse:error:], то вам необходимо изменить их. Ни один из этих двух методов URL-выборки не позволяет отменить запрос. Apple имеет good documentation о том, как использовать асинхронные методы отмены.

Далее выполняется синтаксический анализ данных, которые вы извлекаете. Если вы не получаете заказ в мегабайтах из Интернета, ваш разбор, вероятно, не стоит отмена. Тем не менее, вы должны делать тяжелую работу в фоновом потоке в любом случае:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    //perform parsing 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     if (!self.view.window) 
      return; //won't update UI if we've moved offscreen 
     //call methods to update the UI 
    }); 
}); 

Это будет выполнять синтаксический анализ в определении приоритетов по умолчанию фона очереди на и обновления пользовательского интерфейса (текстовые поля и т.д.) в основной очереди один раз в разборе готово.

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

Смежные вопросы