Zi Yue: Learning without thinking is not the case, thinking without learning is dangerous.
In the previous article: the Egocache cache framework explained in detail that Egocache can set the cache expiration time by default of 1 days. Look at the Egocache source code, set the default time:
[self setDefaultTimeoutInterval:86400]; //86400 = 24 * 60 * 60 刚好是一天时间。
Egocache Why do I have to set the cache expiration time? Or what is the benefit of setting the cache expiration time? I think the biggest benefit is the ability to clear the cache at regular intervals. You can set the cache time for an item, which makes it easy to manage the cache.
So here's the question:
- How does the Egocache detect cache expiration time?
- When the deletion of a cache entry is triggered when the time expires?
With these two questions, let's continue our analysis.
How would you do that?
Remember in the company, bosses often cite such examples:
某某同志,刚来我们公司的时候,遇到问题就知道抱怨。从来不知道去思考怎么解决,只知道把问题抛给领导。工作半年下来,成长了很多。现在碰到问题,不仅把问题抛出来,而且还提供了自己的解决方案...
A similar example is believed to have been heard by everyone. Similarly, since we have put forward these two questions, let us consider first, if we are to do how to solve the problem?
If I were to write it, there were several preliminary approaches to my mind:
- Polling is done through a timer, and is detected every once in a while.
- Write a while loop to detect.
- Each time the cache entry is read, the cache time is determined to be expired. Returns the cached entry that was read without expiring, otherwise, nil is returned.
Of course, there are some methods, not one by one cases. If you think about it, the drawbacks of these methods can be easily revealed.
- For a small cache time, polling with a timer is obviously a waste of resources
- It's almost like Method 1.
- Each time you read the time to determine whether or not to expire, if not read, the app cache will be more and more large, nor desirable.
These methods are excluded, is there a good way? Keep looking down:
How did the Egocache come true?
Carefully review the Egocache source code, found in the Initwithcachedirectory: method, each time the Egocache instance object is initialized, it iterates through all the existing cache entries in the Plist file, compares the time of each cache entry with the current time, Cache entries expire earlier than the current time, delete the corresponding cache file and delete the record of the corresponding key in the plist file.
The specific implementation code is as follows:
Read Cache entry Information
_cacheInfo = [[NSDictionary dictionaryWithContentsOfFile:cachePathForKey(_directory, @"EGOCache.plist")] mutableCopy];if(!_cacheInfo) { _cacheInfo = [[NSMutableDictionary alloc] init];}
Gets the nstimeinterval of the current time
NSTimeInterval now = [[NSDate date] timeIntervalSinceReferenceDate];
Declare Removedkeys save expired cache entries corresponding to key
NSMutableArray* removedKeys = [[NSMutableArray alloc] init];
Traverse cache entry information and determine cache time
for(NSString* key in _cacheInfo) { //判断缓存项过期时间是否早于当前时间 if([_cacheInfo[key] timeIntervalSinceReferenceDate] <= now) { //如果缓存项过期时间早于当前时间,移除缓存项 [[NSFileManager defaultManager] removeItemAtPath:cachePathForKey(_directory, key) error:NULL]; //把过期的缓存项对于的key保存到removedKeys里面 [removedKeys addObject:key]; }}
Delete expired cache entries for the key
[_cacheInfo removeObjectsForKeys:removedKeys];
See these, is not feel people thinking special cow fork, anyway, I think this author is not simple. Is this the right step to solve?
What else did Egocache do?
Careful child shoes will find:Egocache is a single-column class , which means that the entire application cycle is initialized only once.
+ (instancetype)globalCache { static id instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[[self class] alloc] init]; }); return instance;}
It is very correct to determine whether the cache entry is out of date each time it is initialized. Think of a scene:
- The user opens App,egocache is initialized and determines whether the cache entry is out of date.
- If there are just a few cache entries that expire after Egocache is initialized. We can still read this cache entry at this time. That's not right.
Continue to analyze Egocache source discovery, Egocache when reading a cache entry, the first to determine whether the cache entry exists, and then read the cache entry (note: Is the time to read Egocache initialization of the cache entry without expiration, and does not say that it is not expired), Finally, determine whether the read cache entry expires compared to the current time.
The specific implementation is as follows:
- (BOOL)hasCacheForKey:(NSString*)key { //读取EGOCache初始化的时候没有过期的缓存项 NSDate* date = [self dateForKey:key]; if(date == nil) return NO; //判断读取到的缓存项当前是否过期 if([date timeIntervalSinceReferenceDate] < CFAbsoluteTimeGetCurrent()) return NO; return [[NSFileManager defaultManager] fileExistsAtPath:cachePathForKey(_directory, key)];}- (NSDate*)dateForKey:(NSString*)key { __block NSDate* date = nil; dispatch_sync(_frozenCacheInfoQueue, ^{ date = (self.frozenCacheInfo)[key]; }); return date;}
Egocache Detection Cache time expires the idea is worth learning, after encountering similar scenes, can be used for reference.
Author Li Gang is just online (www.superqq.com) webmaster, Baidu hundred column author
iOS engineer non-famous from media, public number iOS development: Iosdevtip operator
?
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Egocache how to detect cache time expiration