YY캐시 (1)

YY캐시 (1)

머리말:

우리는 일반적으로 네트워크에서 요청한 비교적 큰 데이터를 캐시합니다.네트워크가 없거나 요청된 로고가 이전 로고와 일치하여 데이터가 변경되지 않았음을 나타내는 경우 캐시를 사용하여 데이터를 다시 가져오지 않고 로드할 수 있습니다. 여기서는 일반적으로 YYCache를 사용합니다 .

붙여넣은 그래픽 1.png

git위에서 아래 로 가져 가라 YYCache pod.

붙여넣은 그래픽.png

볼 수 있는 파일 구조는 비교적 단순하며 외부용 인터페이스 파일 YYCache외에도 디스크 캐시, 메타 데이터 키-값 저장소 및 메모리 캐시가 있습니다.YYCacheYYDiskCacheYYKVStorageYYMemoryCache

1. YY캐시:

YYCache스레드로부터 안전한 키-값 캐시입니다. YYMemoryCache작고 빠른 메모리 내 캐시에 저장된 개체를 사용 하고 YYDiskCache크고 느린 디스크 캐시에 개체를 유지합니다.

속성 목록:

属性就三个:
@interface YYCache : NSObject
/** 缓存名字,只读*/
@property (copy, readonly) NSString *name;
/** 内存缓存.*/
@property (strong, readonly) YYMemoryCache *memoryCache;
/** 磁盘缓存.*/
@property (strong, readonly) YYDiskCache *diskCache;
复制代码

방법 목록:

초기화:

初始化:
/**
用指定的名称创建一个新实例。
 */
- (nullable instancetype)initWithName:(NSString *)name;
/**
用指定的路径创建一个新实例。
 */
- (nullable instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER;

/**
便捷初始化,用指定的名称创建一个新实例。
 */
+ (nullable instancetype)cacheWithName:(NSString *)name;
/**
便捷初始化,用指定的路径创建一个新实例
 */
+ (nullable instancetype)cacheWithPath:(NSString *)path;
复制代码

액세스 방법:


/**
返回一个布尔值,一个指定的键是否在缓存中,可能会阻塞线程直到文件读取完成。
 */
- (BOOL)containsObjectForKey:(NSString *)key;

/**
返回指定键相对应的值。
 */
- (nullable id<NSCoding>)objectForKey:(NSString *)key;

/**
设置缓存中指定键的值。
 */
- (void)setObject:(nullable id<NSCoding>)object forKey:(NSString *)key;

/**
删除缓存中指定键的值,如果为nil,则此方法无效。
 */
- (void)removeObjectForKey:(NSString *)key;
/**
清空缓存。
 */
- (void)removeAllObjects;
/**
用block清空缓存。可以通过参数得到进度。
 */
- (void)removeAllObjectsWithProgressBlock:(nullable void(^)(int removedCount, int totalCount))progress
                                 endBlock:(nullable void(^)(BOOL error))end;

复制代码

.m파일의 초기화 방법을 살펴보십시오 initWithName.

- (instancetype)initWithName:(NSString *)name {
    if (name.length == 0) return nil;
    NSString *cacheFolder = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
    NSString *path = [cacheFolder stringByAppendingPathComponent:name];
    return [self initWithPath:path];
}
复制代码

Discovery는 initWithName다른 초기화 메소드 initWithPathYYMemoryCache초기화 메소드를 호출합니다.

- (instancetype)initWithPath:(NSString *)path {
    return [self initWithPath:path inlineThreshold:1024 * 20]; // 20KB
}
查看initWithPath:(NSString *)path
             inlineThreshold:(NSUInteger)threshold发现:

- (instancetype)initWithPath:(NSString *)path
             inlineThreshold:(NSUInteger)threshold {
    
    YYKVStorageType type;
    if (threshold == 0) {
        type = YYKVStorageTypeFile;
    } else if (threshold == NSUIntegerMax) {
        type = YYKVStorageTypeSQLite;
    } else {
        type = YYKVStorageTypeMixed;
    }
	_inlineThreshold = threshold;
}
复制代码

YYDiskCache인라인 임계값 에서 볼 수 있듯이 20KB_inlineThreshold로 초기화됩니다 20KB.

YYKVStorageType세 가지 스토리지 유형이 있는지 보려면 클릭하십시오 .
1. 파일 2. 데이터베이스 3. 옵션

typedef NS_ENUM(NSUInteger, YYKVStorageType) {
    /// The `value` is stored as a file in file system.
    YYKVStorageTypeFile = 0,
    
    /// The `value` is stored in sqlite with blob type.
    YYKVStorageTypeSQLite = 1,
    
    /// The `value` is stored in file system or sqlite based on your choice.
    YYKVStorageTypeMixed = 2,
};
复制代码

과제를 다시 살펴보세요.

- (void)setObject:(id<NSCoding>)object forKey:(NSString *)key {
    NSData *value = nil;

    if (!value) return;
    NSString *filename = nil;
    if (_kv.type != YYKVStorageTypeSQLite) {
        if (value.length > _inlineThreshold) {
            filename = [self _filenameForKey:key];
        }
    }
    Lock();
    [_kv saveItemWithKey:key value:value filename:filename extendedData:extendedData];
    Unlock();
}
复制代码

value.length> _inlineThreshold, filename할당됨을 볼 수 있습니다 . 클릭 saveItemWithKey방법:

- (BOOL)saveItemWithKey:(NSString *)key value:(NSData *)value filename:(NSString *)filename extendedData:(NSData *)extendedData {

    if (filename.length) {
        if (![self _fileWriteWithName:filename data:value]) {
            return NO;
        }
        if (![self _dbSaveWithKey:key value:value fileName:filename extendedData:extendedData]) {
            [self _fileDeleteWithName:filename];
            return NO;
        }
        return YES;
    } else {
        if (_type != YYKVStorageTypeSQLite) {
            NSString *filename = [self _dbGetFilenameWithKey:key];
            if (filename) {
                [self _fileDeleteWithName:filename];
            }
        }
        return [self _dbSaveWithKey:key value:value fileName:nil extendedData:extendedData];
    }
}
复制代码

filename.length값이 있으면 파일에 직접 쓰고, 그보다 크지 않으면 쓰기를 20KB사용하는 것을 볼 수 있습니다 sqlite.

작성자 : NSURLCache, FBDiskCache는 SQLite 데이터베이스를 기반으로 합니다. 데이터베이스 기반 캐시는 메타 데이터를 잘 지원할 수 있고 확장이 쉽고 데이터 통계가 빠릅니다 LRU 또는 기타 제거 알고리즘 구현도 쉽습니다 유일한 불확실성은 데이터베이스 읽기 및 쓰기 성능입니다. 실제 온보드 성능의 SQLite. iPhone 6 64G에서 SQLite 쓰기 성능은 직접 파일 쓰기보다 높지만 읽기 성능은 데이터 크기에 따라 달라집니다. 단일 데이터 조각이 20K보다 크면 직접 쓰기 파일에 더 빠릅니다.

2, YYDiskCache:

(동일한 매개변수 및 메서드는 다시 작성되지 않음)

속성 목록:


/**
如果对象的数据大小(以字节为单位)大于此值,则对象将
存储为文件,否则对象将存储在sqlite中。
0表示所有对象将存储为分开的文件,NSUIntegerMax表示所有对象
对象将存储在sqlite中。
默认值为20480 (20KB)。
 */
@property (readonly) NSUInteger inlineThreshold;
/**
如果这个块不是nil,那么这个块将被用来存档对象
NSKeyedArchiver。您可以使用此块来支持不支持的对象
遵守' NSCoding '协议。
默认值为空。
 */
@property (nullable, copy) NSData *(^customArchiveBlock)(id object);
/**
如果这个块不是nil,那么这个块将被用来解存档对象
NSKeyedUnarchiver。您可以使用此块来支持不支持的对象
遵守' NSCoding '协议。
默认值为空。
 */
@property (nullable, copy) id (^customUnarchiveBlock)(NSData *data);
/**
当需要将对象保存为文件时,将调用此块来生成
指定键的文件名。如果块为空,缓存使用md5(key)作为默认文件名。默认值为空。
 */
@property (nullable, copy) NSString *(^customFileNameBlock)(NSString *key);
#pragma mark - Limit
/**
缓存应容纳的最大对象数。
默认值为NSUIntegerMax,即不限制。
这不是一个严格的限制-如果缓存超过限制,缓存中的一些对象
缓存可以稍后在后台队列中被清除。
 */
@property NSUInteger countLimit;
/**
在开始清除对象之前,缓存可以保留的最大总开销。
默认值为NSUIntegerMax,即不限制。
这不是一个严格的限制-如果缓存超过限制,缓存中的一些对象
缓存可以稍后在后台队列中被清除。
 */
@property NSUInteger costLimit;
/**
缓存中对象的最大过期时间。

>值为DBL_MAX,即无限制。
这不是一个严格的限制-如果一个对象超过了限制,对象可以
稍后在后台队列中被驱逐。
 */
@property NSTimeInterval ageLimit;
/**
缓存应保留的最小空闲磁盘空间(以字节为单位)。

>默认值为0,表示不限制。
如果可用磁盘空间低于此值,缓存将删除对象
释放一些磁盘空间。这不是一个严格的限制——如果空闲磁盘空间没有了
超过限制,对象可能稍后在后台队列中被清除。
 */
@property NSUInteger freeDiskSpaceLimit;
/**
自动修整检查时间间隔以秒为单位。默认值是60(1分钟)。
缓存保存一个内部计时器来检查缓存是否达到
它的极限,一旦达到极限,它就开始驱逐物体。
 */
@property NSTimeInterval autoTrimInterval;
/**
设置“YES”为调试启用错误日志。
 */
@property BOOL errorLogsEnabled;
复制代码

방법 목록:

/**
指定的初始化式。
threshold数据存储内联阈值,单位为字节。如果对象的数据
Size(以字节为单位)大于此值,则对象将存储为
文件,否则对象将存储在sqlite中。0表示所有对象都会
NSUIntegerMax表示所有对象都将被存储
sqlite。如果您不知道对象的大小,20480是一个不错的选择。
在第一次初始化后,您不应该更改指定路径的这个值。
如果指定路径的缓存实例在内存中已经存在,
该方法将直接返回该实例,而不是创建一个新实例。
 */
- (nullable instancetype)initWithPath:(NSString *)path inlineThreshold:(NSUInteger)threshold NS_DESIGNATED_INITIALIZER;
/**
返回此缓存中的对象数量。
 */
- (NSInteger)totalCount;
/**
以字节为单位的对象开销总数。
 */
- (NSInteger)totalCost;
#pragma mark - 修剪
/**
使用LRU从缓存中移除对象,直到' totalCount '低于指定值。
 */
- (void)trimToCount:(NSUInteger)count;
/**
使用LRU从缓存中移除对象,直到' totalCost '低于指定值,完成后调用回调。
 */
- (void)trimToCost:(NSUInteger)cost;
/**
使用LRU从缓存中删除对象,直到所有过期对象被指定值删除为止。
 */
- (void)trimToAge:(NSTimeInterval)age;
/**
从对象中获取扩展数据。
 */
+ (nullable NSData *)getExtendedDataFromObject:(id)object;
/**
将扩展数据设置为一个对象。
 */
+ (void)setExtendedData:(nullable NSData *)extendedData toObject:(id)object;

@end
复制代码

3. YY메모리 캐시:

속성 목록:

/** 存中的对象数量(只读)*/
@property (readonly) NSUInteger totalCount;

/** 缓存中对象的总开销(只读)*/
@property (readonly) NSUInteger totalCost;

/**
自动修整检查时间间隔以秒为单位。默认是5.0。
 */
@property NSTimeInterval autoTrimInterval;
/**
如果' YES ',当应用程序收到内存警告时,缓存将删除所有对象。
 */
@property BOOL shouldRemoveAllObjectsOnMemoryWarning;
/**
如果是,当应用程序进入后台时,缓存将删除所有对象。
 */
@property BOOL shouldRemoveAllObjectsWhenEnteringBackground;
/**
当应用程序收到内存警告时要执行的块。
 */
@property (nullable, copy) void(^didReceiveMemoryWarningBlock)(YYMemoryCache *cache);
/**
当应用程序进入后台时执行的一个块。
 */
@property (nullable, copy) void(^didEnterBackgroundBlock)(YYMemoryCache *cache);
/**
如果' YES ',键值对将在主线程上释放,否则在后台线程上释放。默认为NO。。
 */
@property BOOL releaseOnMainThread;
/**
如果' YES ',键值对将在主线程上释放,否则在后台线程上释放。默认为NO。
 */
@property BOOL releaseAsynchronously;
复制代码

요약하다:

NSCache 비교:

@interface NSCache <KeyType, ObjectType> : NSObject
@property (copy) NSString *name;
@property (nullable, assign) id<NSCacheDelegate> delegate;
- (nullable ObjectType)objectForKey:(KeyType)key;
- (void)setObject:(ObjectType)obj forKey:(KeyType)key; // 0 cost
- (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g;
- (void)removeObjectForKey:(KeyType)key;
- (void)removeAllObjects;
@property NSUInteger totalCostLimit;	// limits are imprecise/not strict
@property NSUInteger countLimit;	// limits are imprecise/not strict
@property BOOL evictsObjectsWithDiscardedContent;
@end
@protocol NSCacheDelegate <NSObject>
@optional
- (void)cache:(NSCache *)cache willEvictObject:(id)obj;
@end
复制代码

NSCache비교적 간단하며 YYCache캐시의 수와 수명 주기를 준비하고 제어하기 위한 메모리 및 디스크 캐시용 인터페이스가 많다는 것을 알게 될 것입니다 .

Supongo que te gusta

Origin juejin.im/post/7214024762855505975
Recomendado
Clasificación