測試發(fā)現(xiàn)了一個(gè)古怪的問題茴她,App 在一些低端機(jī)上旱眯,自然息屏软族,再打開的時(shí)候 一些本地圖片會(huì)不見了床牧?(每次 didBecomeActive 的時(shí)候 會(huì)原地刷新一下)
image.png
經(jīng)過各種嘗試痪伦,有個(gè)小伙伴最終復(fù)現(xiàn)了對(duì)應(yīng)場景侄榴。
立馬進(jìn)行 Debug
雹锣,發(fā)現(xiàn)在讀取 本地圖片資源的時(shí)候 就報(bào)錯(cuò)了。癞蚕。蕊爵。
image.png
image.png
這是個(gè)頭疼的問題,Too many open files
google 一下也搞不定桦山。 自己也很難定位具體的原因(哪里文件打開過了攒射,根本不知道。恒水。会放。),該問題在 AppStore(release) 包上不會(huì)復(fù)現(xiàn)钉凌,(可能跟 Debug模式下咧最,有代碼偷偷做了什么。御雕。窗市。)
Too many open files
我們解決不了,那有別的方式繞過這個(gè)問題嗎饮笛?
記錄頁面原地刷新咨察?如何不空大?
下面是核心代碼:
@interface IMYImageMemoryCache ()
@property (nonatomic, strong) YYMemoryCache *memoryCache;
@property (nonatomic, strong) NSMapTable *weakCache;
@property (nonatomic, strong) dispatch_semaphore_t dsem;
@end
@implementation IMYImageMemoryCache
- (id)objectForKey:(id)key {
if (!key) {
return nil;
}
id obj = [_memoryCache objectForKey:key];
if (!obj) {
dispatch_semaphore_wait(_dsem, DISPATCH_TIME_FOREVER);
obj = [_weakCache objectForKey:key];
dispatch_semaphore_signal(_dsem);
if (obj) {
NSUInteger cost = IMYCacheCostForImage(obj);
[_memoryCache setObject:obj forKey:key withCost:cost];
}
}
return obj;
}
- (void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)g {
if (!key) {
return;
}
[_memoryCache setObject:obj forKey:key withCost:g];
dispatch_semaphore_wait(_dsem, DISPATCH_TIME_FOREVER);
[_weakCache setObject:obj forKey:key];
dispatch_semaphore_signal(_dsem);
}
@end
問題1:為啥 MemoryCache 找不到 Image了福青,而 WeakMap 里面還有摄狱?
問題2:該方案還有其他運(yùn)用場景嗎?
這次的方案來自 SDWebImage 5.x 版本的 SDMemoryCache