2015-07-12 1 views
3

Существует множество сторонних библиотек для загрузки сетевого изображения, а затем их хранения в диск и/или память.NSURLSession для загрузки сетевых изображений + кэш

Однако это очень просто для его реализации с использованием простого вызова API NSURLSession.

вот код:

 NSURLCache *myCache = [[NSURLCache alloc] initWithMemoryCapacity: 16384 diskCapacity: 268435456 diskPath: cachePath]; // these numbers are only for the usage example. 
    defaultConfigObject.URLCache = myCache; 
    defaultConfigObject.requestCachePolicy = NSURLRequestUseProtocolCachePolicy; 
    _session = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate:self delegateQueue: [NSOperationQueue mainQueue]]; 

    _dataTask = [_session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){ 

     if (!error){ 
      UIImage* theImage = [UIImage imageWithData:data]; 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       self.image = theImage; 

      }); 
     } 
    }]; 
    [_dataTask resume]; 

Этот код загружает изображение (из данного URL) и сохранить его в памяти + диск в соответствии с политикой кэширования HTTP.

Получение MyNetworkImageView из UIImageView и добавление вышеуказанного кода в метод setURL: также прямолинейный.

Мой вопрос:

Каковы преимущества использования других механизмов третьих сторон, таких как AFNetworking, FastImageCache, SDWebImage, SDImageCache?

+0

Кэширование в 'NSURLSession' зависит от (a) размера загрузки относительно размера кеша; и (б) заголовки ответа. Я бы очень стресс протестировал ваше приложение и убедился, что кеширование (esp persistent cache cache) работает так, как вы думаете. Ваш кэш памяти кажется очень маленьким (и все, что превышает 5% от размера кеша, не будет кэшироваться). Итог, полагаясь на «NSURLCache» в iOS, в прошлом был проблематичным, особенно если вы не контролируете сервер. Эти классы также предлагают другие преимущества (например, с категориями «UIImageView»). – Rob

+0

Спасибо, Роб. Я отредактировал свой вопрос за ваши замечания. в отношении размера кэша памяти, это только для примера использования, там нет реальных рабочих номеров. что касается проблемы NSURLCache в iOS, я вспоминаю такие проблемы, но я считаю, что они больше не актуальны в iOS8 и выше. наконец, предполагая, что сервер определяет поведение кэширования, есть ли больше преимуществ? –

+0

ОК. Обычно я ожидал, что кеш памяти будет в MB, а не в KB. :) Успех кеширования «NSURLCache», я бы предложил только эмпирически проверить это, во-первых. Но если 'NSURLSession' работает для ваших нужд, тогда идите и просто используйте это. Я бы отступил назад и подумал о более широких сетевых потребностях приложения, но если вам не нужно сложное создание/обработка HTTP-запросов, а также категории «UIImageView» и т. Д., Просто используйте «NSURLSession». – Rob

ответ

1
  1. Кэширование в этих рамках более детерминировано. NSURLCache, используемый NSURLSession, является (a) несколько непрозрачным (например, я никогда не видел, чтобы 5% -ый порог был документирован); и (б) контролируются заголовками ответов, предоставленными вашим сервером.

  2. Прежде чем просто объявить NSURLCache «достаточно хорошо», я бы предложил строго протестировать приложение и убедиться, что кеширование (esp постоянный кэш хранения: запуск приложения, загрузка изображений, прекращение (а не просто приостановка) приложения; -run приложение) работает, как вы надеетесь, это так. Обязательно проверяйте как кеширование времени выполнения, так и постоянное кэширование хранилища.

  3. Как в стороне, ваш кэш памяти кажется очень маленьким (и все, что превышает 5% от размера кеша, не будет кэшироваться). Это вопрос мнения, но я обычно ожидал увидеть что-то ближе к 16mb, а не 16kb. Как бы то ни было, это не будет кэшировать ничего, превышающее 800 байтов!

  4. Эти рамки также предлагают множество других преимуществ.

    • В UIImageView категории, предоставляемое AFNetworking и SDWebImage является самым простым способом для достижения асинхронного извлечения изображения. В частности, когда ячейки повторно используются в представлении таблицы/коллекции, он отменяет предыдущие запросы, следя за тем, чтобы запросы изображений для видимых ячеек были приоритетными. (Вы не хотите быстро прокручивать до 100-й строки в таблице и ждать до 99 изображений, не имеющих длинной видимости для загрузки, прежде чем вы начнете загружать изображения для видимых ячеек.)

    • При генерации сложных HTTP-запросов , AFNetworking позволяет сосредоточиться на логике приложений, а не на написании и тестировании сложного сетевого кода.

Нижняя линия, опираясь на NSURLCache в прошивкой была проблематичной в прошлом, особенно если вы не контролируете сервер. Эти классы также предлагают другие преимущества (например, с категориями UIImageView).

+0

Исправьте меня, если я ошибаюсь, но AFNetworking также использует NSURLCache (и по умолчанию не кэширует на диск): https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-FAQ –

+0

@ user2955669 - 'UIImageView' AFNetworking' категория также использует свое собственное руководство 'NSCache'. Но, да, под ним также есть функция «NSURLCache». Но вы можете кэшировать на диск с помощью 'NSURLCache' (например,при условии соблюдения всех ограничений и ограничений «NSURLCache» влечет за собой). 'SDWebImage' делает свое собственное постоянное кэширование хранилища, в прошлый раз я его использовал. – Rob

+0

Также обратите внимание, что «NSURLConnection устарел в iOS9» (https://developer.apple.com/videos/wwdc/2015/?id=711), все равно будет работать, но в конце концов закончится. AFNetworking по-прежнему использует NSURLConnection, но его придется модифицировать для работы только над NSURLSession, поэтому преимущества API AFNetworking API (например, основанные на блоках API) по сравнению с API NSURLConnection также будут обесцениваться. –

0

NSURLCache - отличный инструмент, особенно если вам нужны механизмы повторной аттестации, а NSURLCache обрабатывает прозрачность HTTP прозрачно для вас.NSURLSession также является хорошим step forward для сетей Cocoa.

Тем не менее, не так-то просто реализовать эффективную выборку изображений. Существуют некоторые особые требования, которые могут возникнуть у вас в приложении:

  1. Избегайте декомпрессии изображений на главной теме, что дорого, особенно для jpg.
  2. Имейте отдельный слой кэша в памяти поверх NSURLCache для хранения распакованных изображений и сможете их синхронно извлекать в основной поток. Управление кэшем в памяти не так просто, даже если вы используете NSCache.
  3. Примите некоторые абстракции сверху на сетевом уровне, чтобы иметь возможность добавлять поддержку для большего количества форматов изображений, если это необходимо, например gif или webp. И расширьте выбор изображений другими способами.
  4. Группа запрашивает тот же образ, а не создавать излишние сессии задачи
  5. Уметь preheat images эффективно
  6. Есть способ первой выборки низкого разрешения заполнитель, а затем ждать высокого разрешения изображения

И Больше.

AFNetworking, FastImageCache, SDWebImage, SDImageCache

Ни один из этих рамок используют NSURLSession (некоторые даже имеют свои собственные реализации кэш-диск), пожалуйста, ознакомьтесь с Nuke/DFImageManager вместо этого. Он построен поверх NSURLSession, имеет все перечисленные выше функции, а также имеет несколько подпрограмм, которые объединяют такие вещи, как AFNetworking *, как сетевой стек, и FLAnimatedImage в качестве анимированного GIF-движка и многое другое.

* AFNetworking основан на NSRULSession, но их реализация для извлечения изображений по-прежнему основана на вершине NSURLConnection (AFHTTPRequestOperation).