I'm attempting to master LRU Caching.  It must be thread safe, and it should preferably perform as well as web image-cache, (avg ~1MB).Please take a look to see if there's anything wrong, amiss, etc.ViewController.m (requesting the cache):- (void)viewWillAppear:(BOOL)animated {    self.ricItems = [RicCache getCachedRicItems];}// -------------------------------------------------------- (void)viewWillDisappear:(BOOL)animated {    [RicCache cacheRicItems:self.ricItems];    [super viewWillDisappear:animated];}The Caching Engine:#import RicCache.h#define kMenuStaleSeconds 10@interface RicCache ()+ (NSString *)cacheDirectory;+ (NSString *)appVersion;   // ...used when you update your app.  Keep cache distinct per app version.@end@implementation RicCachestatic NSMutableDictionary *memoryCache;static NSMutableArray *recentlyAccessedKeys;static int kCacheMemoryLimit;+ (void)initialize {    NSString *cacheDirectory = [RicCache cacheDirectory];    if (![[NSFileManager defaultManager] fileExistsAtPath:cacheDirectory]){        [[NSFileManager defaultManager] createDirectoryAtPath:cacheDirectory                                  withIntermediateDirectories:YES                                                   attributes:nil                                                        error:nil];    }    // Invalidating the Cache.    // Check if app's current version is dated; if true, then clear it via 'clearCache':    double lastSavedCacheVersion = [[NSUserDefaults standardUserDefaults] doubleForKey:@CACHE_VERSION];    double currentAppVersion = [[RicCache appVersion] doubleValue];    if (lastSavedCacheVersion == 0.0f || lastSavedCacheVersion < currentAppVersion) {        // assigning current version to preference        [RicCache clearCache];        [[NSUserDefaults standardUserDefaults] setDouble:currentAppVersion forKey:@CACHE_VERSION];        [[NSUserDefaults standardUserDefaults] synchronize];    }    memoryCache = [[NSMutableDictionary alloc] init];    recentlyAccessedKeys = [[NSMutableArray alloc] init];    // you can set this based on the running device and expected cache size    kCacheMemoryLimit = 10;    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveMemoryCacheToDisk:)                                                 name:UIApplicationDidReceiveMemoryWarningNotification                                               object:nil];    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveMemoryCacheToDisk:)                                                 name:UIApplicationDidEnterBackgroundNotification                                               object:nil];    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveMemoryCacheToDisk:)                                                 name:UIApplicationWillTerminateNotification                                               object:nil];}// -------------------------------------------------------+ (void)dealloc {    memoryCache = nil;    recentlyAccessedKeys = nil;    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillTerminateNotification object:nil];}// -------------------------------------------------------#pragma mark -+ (void)saveMemoryCacheToDisk:(NSNotification  *)notification {    @synchronized(self) {        for (NSString *filename in [memoryCache allKeys]){            NSString *archivePath = [[RicCache cacheDirectory] stringByAppendingPathComponent:filename];            NSData *cacheData = [memoryCache objectForKey:filename];            [cacheData writeToFile:archivePath atomically:YES];        }        [memoryCache removeAllObjects];    }}// -------------------------------------------------------+ (void)clearCache {    @synchronized(self) {        NSArray *cachedItems = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[RicCache cacheDirectory]                                                                                   error:nil];        for(NSString *path in cachedItems)            [[NSFileManager defaultManager] removeItemAtPath:path error:nil];        [memoryCache removeAllObjects];    }}// -------------------------------------------------------// ...Getter: getting the current app version from its info.plist.+ (NSString *)appVersion {    CFStringRef versStr = (CFStringRef)CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey);    NSString *version = [NSString stringWithUTF8String:CFStringGetCStringPtr(versStr,kCFStringEncodingMacRoman)];    return version;}// -------------------------------------------------------+ (NSString *)cacheDirectory {    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);    NSString *cachesDirectory = [paths objectAtIndex:0];    return [cachesDirectory stringByAppendingPathComponent:@RicCache];}// -------------------------------------------------------+ (NSData  *)dataForFile:(NSString *)fileName {    NSData *data = [memoryCache objectForKey:fileName];    if (data)return data; // data is present in memory cache    NSString *archivePath = [[RicCache cacheDirectory] stringByAppendingPathComponent:fileName];    data = [NSData dataWithContentsOfFile:archivePath];    if (data)        [self cacheData:data toFile:fileName]; // put the recently accessed data to memory cache    return data;}// -------------------------------------------------------#pragma mark - Caching Data+ (void)cacheData:(NSData *)data toFile:(NSString *)fileName {    @synchronized(self) {        [memoryCache setObject:data forKey:fileName];        if ([recentlyAccessedKeys containsObject:fileName]){            [recentlyAccessedKeys removeObject:fileName];        }        [recentlyAccessedKeys insertObject:fileName atIndex:0];        // Write oldest data to file if cache is full:        if ([recentlyAccessedKeys count] > kCacheMemoryLimit) {            NSString *leastRecentlyUsedDataFilename = [recentlyAccessedKeys lastObject];            NSData *leastRecentlyUsedCacheData = [memoryCache objectForKey:leastRecentlyUsedDataFilename];            NSString *archivePath = [[RicCache cacheDirectory] stringByAppendingPathComponent:fileName];            [leastRecentlyUsedCacheData writeToFile:archivePath atomically:YES];            [recentlyAccessedKeys removeLastObject];            [memoryCache removeObjectForKey:leastRecentlyUsedDataFilename];        }    }}// -------------------------------------------------------#pragma mark - Caching Assessors+ (void)cacheRicItems:(NSArray *)RicItems {    [self cacheData:[NSKeyedArchiver archivedDataWithRootObject:RicItems] toFile:@RicItems.archive];}// -------------------------------------------------------+ (NSMutableArray *)getCachedRicItems {    return [NSKeyedUnarchiver unarchiveObjectWithData:[self dataForFile:@RicItems.archive]];}@end
Thread-safe, in-memory LRU cache with a maximum item count of 10
objective c;thread safety;ios;cache