ПРОГРАММИРОВАНИЕ ПОД IPHONE, IPAD OBJECTIVE-C часть 2

Кэширование данных

Перед тем как начать писать код, я предлагаю разобраться в том, что такое кэш и зачем он нужен. Образно говоря, кэш — это специальный буфер (контейнер), содержащий информацию. Эта информация может быть запрошена с наибольшей вероятностью. Соответственно, доступ к этому буферу должен быть очень быстрым, он должен быть быстрее чем доступ к сети или к данным на жестком диске. В операционной системе iOS присутствует функция кэширования, но прямого доступа к данным в кэше нету. Для я получения доступа следует использовать класс NSCache, о котором и пойдет речь в данном примере.

 

Чаще всего кэширование нам пригодится при работе с сетью. Поэтому я предлагаю далеко не ходить, а воспользоваться примером APIDownload, в котором мы скачивали картинку (как раз эту картинку мы и будем кэшировать). Скачайте проект вышеупомянутого примера и измените файл DownloadViewController.m следующим образом:

 

<code data-result="[object Object]">#import "DownloadViewController.h"

@implementation DownloadViewController

@synthesize logo;
@synthesize downloadProgress;

- (void)dealloc {
    self.logo = nil;
    self.downloadProgress = nil;
    [super dealloc];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.logo = nil;
    self.downloadProgress = nil;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (IBAction)startDownload {
    logo.image = nil;
    downloadProgress.hidden = NO;
    downloadProgress.progress = 0.0f;

    [APIDownload downloadWithURL:@"http://mycrealife.ru/wp-content/uploads/2014/01/logo1.png" delegate:self];
}

- (void)APIDownload:(APIDownload*)request {    
    downloadProgress.hidden = YES;

    UIImage *image = [UIImage imageWithData:request.downloadData];
    logo.image = image;
}

- (void)dataDownloadAtPercent:(NSNumber*)percent {
    downloadProgress.progress = [percent floatValue];
}

@end</code>

 

Ничего военного мы не сделали, просто вынесли код скачивания данных в отдельный метод (этот метод будет вызываться при нажатии на кнопку, не забудте эту кнопку добавить на интерфейс и связать с startDownload). А перед стартом скачивания — удалаяем картинку и устанавливаем начальные значения downloadProgress. Таким образом, картинка будет скачиватся при каждом нажатии на кнопку, а не при загрузке приложения, то есть, мы симулируем необходимость частых запросов к данным в сети.

 

Теперь на сцену выходит специально написаный мной класс APICache (скачайте, добавьте в проект и импортируйте его в DownloadViewController). Добавлять данные в кэш мы будем по окончанию их скачивания:

 

<code data-result="[object Object]">- (void)APIDownload:(APIDownload*)request {    
    downloadProgress.hidden = YES;

    UIImage *image = [UIImage imageWithData:request.downloadData];
    logo.image = image;

    [[APICache sharedAPICache] setObject:image forKey:@"image"];
}</code>

 

Последняя строка метода APIDownload: как раз этим и занимается.

 

А получать данные с кэша перед начало закачки:

 

<code data-result="[object Object]">- (IBAction)startDownload {
    logo.image = nil;

    UIImage *image = [[APICache sharedAPICache] objectForKey:@"image"];
    if (image) {
        logo.image = image;
    } else {
        downloadProgress.hidden = NO;
        downloadProgress.progress = 0.0f;
        [APIDownload downloadWithURL:@"http://mycrealife.ru/wp-content/uploads/2014/01/logo1.png" delegate:self];
    }
}</code>

 

В этом методе, как и раньше, мы удаляем текущую картинку. Затем проверяем, хранится ли в кэше наша картинка. Если хранится — то просто устанавливаем ее, иначе — стартуем закачку. Если у вас очень быстрый интернет — скачивание произойдет в доли секунды и вы не заметите с кэша взялась картинка или с сети. Для выхода с этой ситуации рекомендую на момент тестирования что-то поставить на закачку или изменить ссылку картинки на вот этоу: http://mycrealife.ru/wp-content/uploads/2014/01/iceHD_hires3.jpg.

 

Как вы уже заметили, работа с кэшем очень похожа на работу со словарями. Но здесь есть несколько отличий. У NSCache нету многих методов, которые облегчают работу со словарями, зато этот класс позволяет корректно использовать оперативную память устройства. То есть, класс NSCache хранит объекты в памяти телефона (для быстрейшего доступа к ним), когда эта память заканчивается — выполняется удаление объектов помещенных туда первыми.

 

Исходный код этого проекта можно скачать здесь и отдельно сам класс APICache.