// // MTCacheManager.m // Meet // // Created by ko1o on 2018/8/29. // Copyright © 2018年 ko1o. All rights reserved. // #import "MTCacheManager.h" #import "MMKV.h" static NSString * const kMTCacheManagerDefaultID = @"kMTCacheManagerDefaultID"; static NSString *(^gSetupBlock)(void); @interface MTCacheManager () @property (nonatomic, strong) MMKV *mmkv; @property (nonatomic, copy) NSString *ID; @end @implementation MTCacheManager + (void)load { #if DEBUG dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ id object = nil; [[MTCacheManager defaultCacheManager]setObject:@(1) forKey:@"_1"]; object = [[MTCacheManager defaultCacheManager] objectOfClass:NSNumber.class forKey:@"_1"]; NSAssert([object integerValue] == 1, @"int value error"); [[MTCacheManager defaultCacheManager]setObject:@(1.1) forKey:@"_1.1"]; object = [[MTCacheManager defaultCacheManager] objectOfClass:NSNumber.class forKey:@"_1.1"]; float floatVlaue = [object floatValue]; NSAssert(fabs(floatVlaue- 1.1) < 0.00001, @"float value error"); [[MTCacheManager defaultCacheManager]setObject:@"stringValue" forKey:@"string"]; object = [[MTCacheManager defaultCacheManager] objectOfClass:NSString.class forKey:@"string"]; NSAssert([object isEqualToString:@"stringValue"], @"stringValue value error"); unsigned long long value = 10000000; [[MTCacheManager defaultCacheManager]setObject:@(value) forKey:@"10000000"]; object = [[MTCacheManager defaultCacheManager] objectOfClass:NSNumber.class forKey:@"10000000"]; NSAssert([object unsignedLongValue] == 10000000, @" unsigned long long error"); [[MTCacheManager defaultCacheManager]setObject:@{@"key":@"hello"} forKey:@"map"]; object = [[MTCacheManager defaultCacheManager] objectOfClass:NSDictionary.class forKey:@"map"]; NSAssert([ object isKindOfClass:[NSDictionary class]] && [[(NSDictionary *)object objectForKey:@"key"]isEqualToString:@"hello"] , @"map"); [[MTCacheManager defaultCacheManager]setObject:@[@1] forKey:@"array"]; object = [[MTCacheManager defaultCacheManager] objectOfClass:NSArray.class forKey:@"array"]; NSAssert([ object isKindOfClass:[NSArray class]] && [((NSArray *)object).firstObject integerValue] == 1, @"array"); [[MTCacheManager defaultCacheManager] setInteger:9999 forKey:@"9999"]; NSAssert([[MTCacheManager defaultCacheManager]integerForKey:@"9999"] == 9999, @"setInteger error"); NSAssert([[MTCacheManager defaultCacheManager]containsKey:@"9999"] &&[[MTCacheManager defaultCacheManager]containsKey:@"_1"] &&[[MTCacheManager defaultCacheManager]containsKey:@"array"] , @"contain error"); [[MTCacheManager defaultCacheManager] removeValueForKey:@"9999"]; [[MTCacheManager defaultCacheManager] removeValueForKey:@"_1"]; [[MTCacheManager defaultCacheManager] removeValueForKey:@"array"]; NSAssert(![[MTCacheManager defaultCacheManager]containsKey:@"9999"] &&![[MTCacheManager defaultCacheManager]containsKey:@"_1"] &&![[MTCacheManager defaultCacheManager]containsKey:@"array"] , @"removeValueForKey error"); size_t size = [[MTCacheManager defaultCacheManager] totalSize]; }); #endif } + (void)setupCacheManager:(NSString * _Nullable (^)(void))setupBlock { if (setupBlock) { gSetupBlock = [setupBlock copy]; } } + (instancetype)userPersistanceManager { NSString *uid = @""; if (gSetupBlock) { uid = gSetupBlock(); } return [self persistanceManagerWithID:uid]; } //持久的数据,不会被清理缓存 + (instancetype)userTemporaryManager {//暂时性数据,会清缓存 NSString *uid = @""; if (gSetupBlock) { uid = gSetupBlock(); } return [self temporaryManagerWithID:uid]; } + (instancetype)defaultCacheManager { static MTCacheManager * _defaultCacheManager; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _defaultCacheManager = [[MTCacheManager alloc]initWithID:kMTCacheManagerDefaultID]; }); return _defaultCacheManager; } + (instancetype)temporaryManagerWithID:(NSString *)ID { if (!ID || ID.length == 0) { return nil; } static MTCacheManager * _manager; @synchronized(self) { if (!_manager || ![_manager.ID isEqualToString:ID]) { _manager = [[MTCacheManager alloc]initWithID:ID]; } } return _manager; } + (instancetype)persistanceManagerWithID:(NSString *)ID { if (!ID || ID.length == 0) { return nil; } static MTCacheManager * _persistanceManager; @synchronized(self) { NSString *key = [NSString stringWithFormat:@"persistance_%@",ID]; if (!_persistanceManager || ![_persistanceManager.ID isEqualToString:key]) { _persistanceManager = [[MTCacheManager alloc]initWithID:key]; } } return _persistanceManager; } - (instancetype)initWithID:(NSString *)ID { if (self = [super init]) { self.mmkv = [MMKV mmkvWithID:ID]; self.ID = ID; } return self; } - (BOOL)setObject:(id)obj forKey:(NSString *)key { if([obj isKindOfClass:NSString.class] || [obj isKindOfClass:NSData.class] ||[obj isKindOfClass:NSDate.class]) { // object: NSString/NSData/NSDate return [self.mmkv setObject:obj forKey:key]; } else { //兼容不支持的类型,用归档 id data = [NSKeyedArchiver archivedDataWithRootObject:obj]; return [self.mmkv setObject:data forKey:key]; } return NO; } - (id) objectOfClass:(Class)cls forKey:(NSString *)key { if([cls isSubclassOfClass:NSString.class] || [cls isSubclassOfClass:NSData.class] ||[cls isSubclassOfClass:NSDate.class]) { // object: NSString/NSData/NSDate id object = [self.mmkv getObjectOfClass:cls forKey:key]; return object; } else { id object = [self.mmkv getObjectOfClass:[NSData class] forKey:key]; id result = [NSKeyedUnarchiver unarchiveObjectWithData:object]; return [result isKindOfClass:cls]? result : nil; } return nil; } - (BOOL)boolForKey:(NSString *)key { return [self.mmkv getBoolForKey:key]; } - (NSInteger)integerForKey:(NSString *)key { return [self.mmkv getInt64ForKey:key]; } - (double)doubleForKey:(NSString *)key { return [self.mmkv getDoubleForKey:key]; } - (void)setBool:(BOOL)val forKey:(NSString *)key { [self.mmkv setBool:val forKey:key]; } - (void)setInteger:(NSInteger)intval forKey:(NSString *)key { [self.mmkv setInt64:intval forKey:key]; } - (void)setDouble:(double)val forKey:(NSString *)key { [self.mmkv setDouble:val forKey:key]; } - (void)removeValueForKey:(NSString *)key { [self.mmkv removeValueForKey:key]; } - (BOOL)containsKey:(NSString *)key { return [self.mmkv containsKey:key]; } - (void)clearAll { [self.mmkv clearAll]; } - (size_t)totalSize { size_t size = [self.mmkv totalSize]; return size; } @end