2016-05-15 4 views
1

недавно я создал пост: NSData caching routineNSData хранится где-то

Но теперь я хочу, чтобы быть более конкретным в том, что я прошу.

Видите ли, у меня есть «карусель», то есть на самом деле вид прокрутки с 7 изображениями. Когда он впервые появляется, он загружает изображения из Интернета и автоматической прокрутки.

Моя проблема заключается в том, что я не хочу, чтобы изображения загружались при каждом прокрутке. К счастью, в фоновом режиме работает некоторая механика «кеша». Таким образом, когда он загружает все изображения, прекращает приложение, а затем запускается без подключения к Интернету, все изображения уже установлены, поэтому он каким-то образом загружает его откуда-то.

Существует код я использую:

NSError *error; 
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@", WEBSITE, mdl.imageSubUrl]] options:NSDataReadingUncached error:&error];; 
NSLog(@"data size0? %lu", (unsigned long)data.length); 

И это. Вы можете попробовать самостоятельно, загрузив изображение, затем перезагрузите приложение в режиме полета и проверьте длину байта. Будут данные, даже когда я его ищу, и там сказано, что dataWithContentsOfURL не делает кеш.

Итак, я хочу просто проверить, есть ли данные, а если нет, не загружайте. Что-то вроде этого:

if (haveData){ 

self.ivPic.image = [UIImage imageWith:myData]; 

} else { 


    NSError *error; 
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@", WEBSITE, mdl.imageSubUrl]] options:NSDataReadingUncached error:&error];; 
    NSLog(@"data size0? %lu", (unsigned long)data.length); 

} 

К сожалению, я не знаю, как сделать такой тест (если есть данные). Во-вторых, я не совсем уверен, как загружать хранимые данные, а не dataWithContentsOfURL, который начнет загрузку с хоста.

+0

Использование SDWebImage. – Wain

+0

Вы можете попробовать UIImageView + AFNetworking.h категорию AFNetworking [ссылка] (http://cocoadocs.org/docsets/AFNetworking/2.0.0/Categories/UIImageView+AFNetworking.html). Это решит вашу цель таким образом, что не нужно обрабатывать кеширование, потому что AFNetworking позаботится об этом. –

+0

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

ответ

1

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

  1. При запуске приложения создайте объект NSCache.

  2. Для того, чтобы загрузить изображение, выполните следующие действия в: NSCache.

  3. Если нет, то увидеть, если изображение находится в папке NSCachesDirectory в файловой системе, если здесь, но не в NSCache, не забудьте обновить NSCache соответственно.

  4. Если найдено ни в одном NSCache ни NSCachesDirectory, запросить его асинхронно из сети (с использованием NSURLSession), и если вы успешно нашли изображение, обновлять и NSCache и NSCachesDirectory соответственно.

  5. BTW, после UIApplicationDidReceiveMemoryWarningNotification, не забудьте очистить NSCache.

Это может выглядеть примерно так:

NSString *filename = [webURL lastPathComponent]; 
NSURL *fileURL; 

// look in `NSCache` 

NSData *data = [self.cache objectForKey:filename]; 

// if not found, look in `NSCachesDirectory` 

if (!data) { 
    NSError *error; 
    NSURL *cacheFileURL = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:false error:&error]; 
    fileURL = [cacheFileURL URLByAppendingPathComponent:filename]; 
    data = [NSData dataWithContentsOfURL:fileURL]; 

    // if found, update `NSCache` 

    if (data) { 
     [self.cache setObject:data forKey:filename]; 
    } 
} 

// if still not found, retrieve it from the network 

if (!data) { 
    [[NSURLSession sharedSession] dataTaskWithURL:webURL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
     if (error) { 
      // handle error 
      return; 
     } 

     UIImage *image = [UIImage imageWithData:data]; 

     // if image retrieved successfully, now save it 
     if (image) { 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       [self.cache setObject:data forKey:filename]; 
       NSError *fileError; 
       [data writeToURL:fileURL options:NSDataWritingAtomic error:&fileError]; 
      }); 
     } 
    }]; 
} 

Сказав все это, я согласен с другими, что это стоит попробовать UIImageView категории, найденные в любом SDWebImage и/или AFNetworking. Они могут делать то, что вам нужно, с гораздо меньшей работой.

+0

как именно я должен проверить, сохранен ли файл в кеше? В моем случае он где-то хранится, но я не могу понять, где –

+0

Проверяя, находится ли он в 'NSCache', вы должны использовать' objectForKey'. Проверяя, находится ли он в 'NSCachesDirectory', вы будете использовать' dataWithContentsOfURL'. – Rob

+0

спасибо Я попробую! –

1
  • Во-первых, вы должны проверить тип:
  • Got по этой ссылке: Я дал мой ответ здесь: Check type of class an NSData store?

    Надеюсь, что это помогает.

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