Design and Implementation of a Hybrid Memory‑Disk Cache Using YYCache in iOS
This article explains the principles of caching, compares memory and disk storage, demonstrates several iOS persistence methods, and details how YYCache combines memory and disk layers with LRU optimization and network synchronization to improve performance in a real‑world mobile app.
The author, an iOS developer at a home‑decoration platform, describes the need for a cache layer (memory & disk) combined with a network layer, and uses YYCache as the reference implementation.
Understanding cache : Cache stores data locally either in memory (fast, small) or on disk (large, slower). iOS sandbox directories (Documents, Library, tmp) are introduced, and the two storage types are illustrated.
How to cache data :
NSKeyedArchiver – archive objects that conform to NSCoding . 1 // Custom Person implements archiving 2 // .h file 3 #import 4 @interface Person : NSObject 5 @property (nonatomic, copy) NSString *name; 6 @end 7 // .m file 8 @implementation Person 9 - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:_name forKey:@"name"]; } 10 - (instancetype)initWithCoder:(NSCoder *)aDecoder { if (self = [super init]) { _name = [aDecoder decodeObjectForKey:@"name"]; } return self; } 11 @end
NSUserDefaults – key‑value storage for simple types. [[NSUserDefaults standardUserDefaults] setObject:@"value" forKey:@"key"]; id obj = [[NSUserDefaults standardUserDefaults] objectForKey:@"key"];
Write – write raw NSData to a file. NSData *data = ...; [data writeToFile:FileName atomically:YES]; NSData *read = [NSData dataWithContentsOfFile:FileName];
SQLite – use a lightweight database for structured data. if (sqlite3_open([databaseFilePath UTF8String], &database) == SQLITE_OK) { NSLog(@"sqlite database is opened."); } else { return; } // create table, insert, etc.
Cache optimization :
Combine memory and disk: request memory first, fall back to disk, then store result back in memory.
Memory optimization with LRU: YYMemoryCache uses a doubly linked list ( _YYLinkedMapNode ) to move frequently accessed items to the head. - (void)bringNodeToHead:(_YYLinkedMapNode *)node { if (_head == node) return; if (_tail == node) { _tail = node->_prev; _tail->_next = nil; } else { node->_next->_prev = node->_prev; node->_prev->_next = node->_next; } node->_next = _head; node->_prev = nil; _head->_prev = node; _head = node; }
Disk optimization: YYDiskCache stores small values in SQLite and large ones as files, automatically selects storage type, supports LRU eviction, cost/count/age limits, and can evict when space is low.
Network‑cache synchronization :
The article shows a flow where each API has a version/ETag; the client sends the cached version, the server returns 304 if unchanged, otherwise new data is cached. Sample code demonstrates switching between cache‑only and network‑plus‑cache strategies.
- (void)getDataWithPage:(NSNumber *)page pageSize:(NSNumber *)pageSize option:(DataSourceOption)option completion:(void(^)(HomePageListCardModel * _Nullable, NSError * _Nullable))completionBlock {
NSString *cacheKey = CacheKey(currentUser.userId, PlatIndexRecommendation);
switch (option) {
case DataSourceCache:
if ([_cache containsObjectForKey:cacheKey]) {
completionBlock((HomePageListCardModel *)[_cache objectForKey:cacheKey], nil);
} else {
completionBlock(nil, LJDError(400, @"缓存中不存在"));
}
break;
case DataSourceNetwork:
[NetWorkServer requestDataWithPage:page pageSize:pageSize completion:^(id _Nullable responseObject, NSError * _Nullable error) {
if (responseObject && !error) {
HomePageListCardModel *model = [HomePageListCardModel yy_modelWithJSON:responseObject];
if (model.errnonumber == 304) {
completionBlock((HomePageListCardModel *)[_cache objectForKey:cacheKey], nil);
} else {
completionBlock(model, nil);
[_cache setObject:model forKey:cacheKey];
}
} else {
completionBlock(nil, error);
}
}];
break;
default:
break;
}
}Conclusion : The hybrid cache design improves UI responsiveness, reduces network traffic, and leverages thread‑safe implementations, asynchronous releases, and low‑level optimizations. The author advises adapting the design to project needs rather than blindly copying.
Beike Product & Technology
As Beike's official product and technology account, we are committed to building a platform for sharing Beike's product and technology insights, targeting internet/O2O developers and product professionals. We share high-quality original articles, tech salon events, and recruitment information weekly. Welcome to follow us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.