2013-05-24 2 views
1

У меня есть приложение, которое загружает несколько фотографий с Flickr. Прямо сейчас, все фотографии загружаются с помощью пользовательского класса NSOperation, работающего на NSOperationQueue. Однако, я слышал о более эффективном асинхронном асинхронном режиме NSUrlConnection и задавался вопросом, что лучше в этой ситуации? Или, есть ли третий вариант, который даже лучше, чем эти два? Обычай NSOperation просто называет [NSData dataWithContentsOfURL:] много раз на разных фотографиях.NSOperation Queue vs NSUrlConnection async

+0

Я сделал оба. Through-put был сопоставим, и подход «NSOperation» был более простым и элегантным. Сказав, что трудно оценить эффективность вашего пользовательского «NSOperation», не зная, что он делает. Третий вариант - это система рычагов, например ['AFNetworking'] (https://github.com/AFNetworking/AFNetworking). – Rob

+0

Если мы рекомендуем сторонние сетевые библиотеки, есть AFNetworkKit, который стоит рассмотреть. – CouchDeveloper

+0

@CouchDeveloper AFNetworkKit? Вы имели в виду ['MKNetworkKit'] (https://github.com/MugunthKumar/MKNetworkKit)? Переходя к вопросу OP, мне нравится тот факт, что 'AFNetworking' создает выделенный поток для сетевых операций, а не то, что делает MKNetworkKit', а именно добавление сетевых операций в основную очередь. В большинстве сценариев они должны быть эквивалентными, но изоляция сетевого потока кажется разумной. – Rob

ответ

5

Использование подхода, который использует подкласс NSOperation и который инкапсулирует NSURLConnection, который используется в асинхронном режиме (реализация протоколов делегата), вероятно, является наиболее эффективным, если и только если вы дополнительно рассмотреть эти аспекты:

Убедитесь, что NSOperation подкласс обрабатывает методы делегирования быстро и что потолочный поток (или очередь) НЕ будет использоваться для процесса данных ответа. В идеале, методы делегата передают данные частичного ответа в другую очередь или поток, где они обрабатываются (обратите внимание: данные изображения могут быть предварительно загружены в фоновый поток или очередь!).

Причина в том, что чем скорее закончится работа в сети, тем больше запросов может быть выполнено за раз. Сетевое NSOperation должно быть помещено в NSOperationQueue, максимальные параллельные операции которого равны 1 или 2. Редко до 4 или выше. Этот параметр зависит от того, поддерживает ли сервер конвейерную обработку и скорость соединения. Назовите эту очередь «Network bound queue».

Задача «процесс обработки данных» (preload image data) также является подклассом NSOperation. Аналогично, операции «процесса обработки данных» должны быть поставлены в очередь в CPU, связанном с NSOperationQueue. По умолчанию максимальные параллельные операции NSOperationQueue уже подходят для операций с привязкой к ЦП.

Если вы хотите сохранить данные на диск, опять же, в идеале вы создадите NSOperation и поставите эти операционные системы в очередь на диске. На устройствах это кажется не необходимым, но если у вас все еще есть такие старые «диски», то имеет смысл установить количество максимальных одновременных операций на количество независимых головок диска. ;)

Ну, это все может сделать только разницу, когда соединение действительно быстрое, и если вы сможете обрабатывать столько данных за одно и то же время.Мы говорим о 5 Мбайтах в секунду на устройстве и, вероятно, 25 Мбайт в секунду на лабораторном столе.

+2

+1 Я согласен с большинством из этого. Я мог бы только опробовать re 'maxConcurrentOperationCount', который я обычно устанавливаю в 4 или 5, и я считаю, что он предлагает значительное улучшение производительности более 1 или 2. Определенно не более 4 или 5, но использование значений, превышающих 1 или 2, может привести к при существенном улучшении производительности. – Rob

+0

Эй, соглашайся с тобой. Я изменил его с 1 на 4 и увидел огромный скачок производительности. – charleyh

+0

Это то, что вам нужно протестировать в реальной среде. Как правило, если соединение стабильно и быстро, вы видите лучшую производительность с двумя или более параллельными сетевыми операциями. Когда ваши соединения действительно быстрые (LTE), у вас может возникнуть проблема с обработкой этих данных, даже если вы распространяете работу на всех доступных ЦП;) – CouchDeveloper

0

Попробуйте эти уроки могут помочь вам:

  1. http://maniacdev.com/2010/03/easier-threading-with-nsoperation-for-better-performance

  2. http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues

  3. http://www.icodeblog.com/2012/10/19/tutorial-asynchronous-http-client-using-nsoperationqueue/

ИЛИ

Если вы загружаете фотографии и показывать их в ячейке таблицы, то вы можете использовать Lazy loading images.

+0

Я знаю, как это сделать, я спрашиваю, какой метод более эффективен. – charleyh

+0

Первый (http://maniacdev.com/2010/03/easier-threading-with-nsoperation-for-better-performance) более эффективен. – iDeveloper

0

Я бы рекомендовал использовать AFNetworking (AFNetworking on Github) , который имеет встроенную функциональность для массового обслуживания операций. Если вы используете его только для загрузки изображений, которые должны отображаться в ячейке таблицы, вы можете использовать категорию AFNetworking в UIImageView для загрузки этих изображений асинхронно.

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