Предистория появления класса MemCache тривиальна. Есть в разработке проект который большую часть времени занимается подгрузкой небольших объемов данных из сети. В основном JSON данные и небольшие изображения. В каждом контроллере был объявлен NSMutableDictionary в котором и сохранялись результаты запросов. Но с ростом количества контроллеров возникло две проблемы — дублирование кода и потеря результатов кеширования при вызове popViewController.
Под катом решение этих проблем.
Было решено провести рефакторинг по проекту в результате которого родился класс-синглтон MemCache и две категории, по одной для NSString и NSObject.
Класс MemCache должен был выполнять кэширование на небольшое время (в этом проекте было достаточно двух минут), самостоятельно очищать память при возникновении MemoryWarning, а также при переходе приложения в фон.
Ссылка на исходники в конце статьи, а пока расскажу про основные этапы реализации.
В методе init подписываемся на уведомления о memory warnings и потере активности.
Не забываем отписаться от уведомлений в dealloc.
Так как кэш может быть очищен в любой момент времени по запросу или по наступлении описанных выше событий, при записи нового элемента нужно проверять, а есть ли собственно куда писать. Для каждого элемента при добавлении запускаем отложенный вызов метода удаления его из кэша.
Для удобства использования использовал категории. Теперь чтобы положить объект в кэш, достаточно написать что-то вроде:
А достать объект можно так:
Ссылка на репозиторий — github.com/eltiren/MemCahce-IOS
P.S. Компилировал с включенным ARC.
Под катом решение этих проблем.
Было решено провести рефакторинг по проекту в результате которого родился класс-синглтон MemCache и две категории, по одной для NSString и NSObject.
Класс MemCache должен был выполнять кэширование на небольшое время (в этом проекте было достаточно двух минут), самостоятельно очищать память при возникновении MemoryWarning, а также при переходе приложения в фон.
Ссылка на исходники в конце статьи, а пока расскажу про основные этапы реализации.
В методе init подписываемся на уведомления о memory warnings и потере активности.
- (id) init { self = [super init]; if (self != nil) { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(clearCache) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; [center addObserver:self selector:@selector(clearCache) name:UIApplicationWillResignActiveNotification object:nil]; _lifeTime = 60.0f; } return self; }
Не забываем отписаться от уведомлений в dealloc.
- (void)dealloc { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; [center removeObserver:self name:UIApplicationWillResignActiveNotification object:nil]; }
Так как кэш может быть очищен в любой момент времени по запросу или по наступлении описанных выше событий, при записи нового элемента нужно проверять, а есть ли собственно куда писать. Для каждого элемента при добавлении запускаем отложенный вызов метода удаления его из кэша.
- (void)setValue:(id)value forKey:(NSString *)key { if (!_cache) { _cache = [[NSMutableDictionary alloc] init]; } [_cache setValue:value forKey:key]; [NSObject cancelPreviousPerformRequestsWithTarget:_cache selector:@selector(removeObjectForKey:) object:key]; [_cache performSelector:@selector(removeObjectForKey:) withObject:key afterDelay:_lifeTime]; }
Для удобства использования использовал категории. Теперь чтобы положить объект в кэш, достаточно написать что-то вроде:
[jsonValue setMemCacheValueForKey:[[[connection originalRequest] URL] absoluteString]];
А достать объект можно так:
id val = [[url absoluteString] memCacheValue];
Ссылка на репозиторий — github.com/eltiren/MemCahce-IOS
P.S. Компилировал с включенным ARC.
