首页 > 其他分享 >iOS开发基础114-YYCache

iOS开发基础114-YYCache

时间:2024-07-17 13:08:27浏览次数:12  
标签:缓存 forKey YYCache iOS 114 NSString key id

YYCache 是一个高性能、易用的缓存组件,广泛用于 iOS 开发中。其设计宗旨是高效且灵活,可以处理不同类型的缓存需求。以下将介绍 YYCache 的常见应用场景,并深入分析其底层原理。

应用场景

1. 图片缓存

在展示大量图像的应用(比如社交媒体应用)中,缓存机制可以大幅减少网络请求,提升用户体验。

示例代码:

#import <YYCache/YYCache.h>

YYCache *imageCache = [YYCache cacheWithName:@"ImageCache"];

- (void)cacheImage:(UIImage *)image forKey:(NSString *)key {
    [imageCache setObject:image forKey:key];
}

- (UIImage *)cachedImageForKey:(NSString *)key {
    return (UIImage *)[imageCache objectForKey:key];
}

2. 网络数据缓存

对于数据频繁更新但实例间访问时间间隔较大的应用,可以使用缓存来保存网络请求的数据,减少无效网络请求。

示例代码:

#import <YYCache/YYCache.h>

YYCache *dataCache = [YYCache cacheWithName:@"DataCache"];

- (void)cacheResponseData:(NSData *)data forKey:(NSString *)key {
    [dataCache setObject:data forKey:key];
}

- (NSData *)cachedResponseDataForKey:(NSString *)key {
    return (NSData *)[dataCache objectForKey:key];
}

3. 用户会话数据缓存

在拥有用户登录功能的应用中,可以缓存用户会话数据以加快登录速度和提高用户体验。

示例代码:

#import <YYCache/YYCache.h>

YYCache *userSessionCache = [YYCache cacheWithName:@"UserSessionCache"];

- (void)cacheUserSession:(NSDictionary *)session forKey:(NSString *)key {
    [userSessionCache setObject:session forKey:key];
}

- (NSDictionary *)cachedUserSessionForKey:(NSString *)key {
    return (NSDictionary *)[userSessionCache objectForKey:key];
}

底层原理分析

1. 内存缓存(YYMemoryCache)

数据结构

YYMemoryCache 中,主要使用了 NSCacheLinkedHashMap 这一系列数据结构来管理缓存。

@interface YYMemoryCache : NSObject

@property (readonly) NSUInteger totalCost;
@property (readonly) NSUInteger totalCount;

- (void)setObject:(id)object forKey:(id)key;
- (void)setObject:(id)object forKey:(id)key withCost:(NSUInteger)cost;
- (id)objectForKey:(id)key;
- (void)removeObjectForKey:(id)key;
- (void)removeAllObjects;

@end

功能和机制

  1. LRU策略YYMemoryCache 使用和维护 LRU (Least Recently Used) 策略,实现数据淘汰。
  2. 线程安全:通过读写锁 (dispatch_semaphore_t) 确保线程安全。
  3. 自动清理:利用 NSCache 内置的自动清理机制,能在内存压力增大时自动清理缓存。

示例代码:

- (id)objectForKey:(id)key {
    if (!key) return nil;
    YYKVStorageItem *node = NULL;
    OSSpinLockLock(&_lock);
    node = (YYKVStorageItem *)CFDictionaryGetValue(_cache, (__bridge const void *)(key));
    if (node) {
        if (_shouldAnimate && node->release_message) {
            [node->release_message workInProgress];
        }
        [_linkedMap bringToHead:node];
    }
    OSSpinLockUnlock(&_lock);
    return node ? node->value : nil;
}

2. 磁盘缓存(YYDiskCache)

数据结构

磁盘缓存使用了自定义的文件系统存储方式以及SQLite数据库进行文件索引管理。

@interface YYDiskCache : NSObject

@property (readonly) NSUInteger totalSize;
@property (readonly) NSUInteger totalCount;

- (void)setObject:(id)object forKey:(id)key;
- (id)objectForKey:(id)key;
- (void)removeObjectForKey:(id)key;
- (void)removeAllObjects;

@end

功能和机制

  1. 文件存储:实际数据被序列化后存储在文件系统中的专用目录下。
  2. SQLite索引:SQLite 数据库用于管理文件的索引,存储键、文件名以及其他元数据。
  3. 自动清理:通过时间或者存储空间来判断是否进行淘汰。

示例代码:

- (id)objectForKey:(id)key {
    if (!key) return nil;
    NSString *filename = [self _filenameForKey:key];
    NSData *data = [NSData dataWithContentsOfFile:filename options:(NSDataReadingOptions)0 error:NULL];
    id object = [_itransformer transformToObjectForData:data];
    if ([data length] > 0) {
        NSString *sql = @"update manifest set access_time = ?1, access_count = access_count + 1 where key = ?2;";
        sqlite3_stmt *stmt = NULL;
        int result = sqlite3_prepare(_db, sql.UTF8String, -1, &stmt, NULL);
        if (result == SQLITE_OK) {
            sqlite3_bind_int(stmt, 1, (int)time(NULL));
            sqlite3_bind_text(stmt, 2, key.UTF8String, -1, NULL);
            result = sqlite3_step(stmt);
            if (result != SQLITE_DONE) {}
        }
        sqlite3_finalize(stmt);
        return object;
    } else {
        return nil;
    }
}

数据同步和异步

  1. 同步操作:对于小数据操作,如键值对的设定和提取,可以进行同步操作。
  2. 异步操作:对于较大数据操作,如下载大文件的缓存保存,提供异步接口以避免主线程阻塞。

示例代码:

- (void)setObject:(id)object forKey:(NSString *)key withBlock:(void(^)(void))block {
    if (!key || !object) {
        if (block) block();
        return;
    }
    dispatch_async(_queue, ^{
        [self setObject:object forKey:key];
        if (block) block();
    });
}

当然,YYCache 的应用场景非常广泛,除了前面提到的图片缓存、网络数据缓存和用户会话数据缓存,还有其他诸多场景。在这些场景中,YYCache 可以发挥其高效缓存的特性,提升应用性能和用户体验。以下是一些其他常见的应用场景以及详细的介绍和实现细节:

其他应用场景

4. 配置文件缓存

对于一些较大但不频繁变化的配置文件,可以使用缓存来减少读取次数,提高访问速度。

示例代码:

#import <YYCache/YYCache.h>

YYCache *configCache = [YYCache cacheWithName:@"ConfigCache"];

- (void)cacheConfig:(NSDictionary *)config forKey:(NSString *)key {
    [configCache setObject:config forKey:key];
}

- (NSDictionary *)cachedConfigForKey:(NSString *)key {
    return (NSDictionary *)[configCache objectForKey:key];
}

5. 搜索历史缓存

在搜索功能中记录并缓存搜索历史,以便下次快速展示用户的搜索历史记录。

示例代码:

#import <YYCache/YYCache.h>

YYCache *searchHistoryCache = [YYCache cacheWithName:@"SearchHistoryCache"];

- (void)cacheSearchHistory:(NSArray *)history forKey:(NSString *)key {
    [searchHistoryCache setObject:history forKey:key];
}

- (NSArray *)cachedSearchHistoryForKey:(NSString *)key {
    return (NSArray *)[searchHistoryCache objectForKey:key];
}

6. 地图数据缓存

对于基于地图的应用,可以缓存地图数据(如离线地图、地理位置数据等)来减少数据加载时间。

示例代码:

#import <YYCache/YYCache.h>

YYCache *mapDataCache = [YYCache cacheWithName:@"MapDataCache"];

- (void)cacheMapData:(NSData *)data forKey:(NSString *)key {
    [mapDataCache setObject:data forKey:key];
}

- (NSData *)cachedMapDataForKey:(NSString *)key {
    return (NSData *)[mapDataCache objectForKey:key];
}

7. 表单数据缓存

对于需要频繁填写表单的应用,可以使用缓存来保存用户填写的数据,方便用户下次填写时自动补全。

示例代码:

#import <YYCache/YYCache.h>

YYCache *formDataCache = [YYCache cacheWithName:@"FormDataCache"];

- (void)cacheFormData:(NSDictionary *)formData forKey:(NSString *)key {
    [formDataCache setObject:formData forKey:key];
}

- (NSDictionary *)cachedFormDataForKey:(NSString *)key {
    return (NSDictionary *)[formDataCache objectForKey:key];
}

深入分析其底层原理

1. 数据更新策略

YYCache 支持两种缓存更新策略:直接覆盖和版本控制。对于直接覆盖,新的数据会直接替换旧的数据。而对于版本控制,开发者可以引入版本信息,用于保持不同版本的数据。

示例代码:

YYCache *cache = [YYCache cacheWithName:@"ExampleCache"];

// 直接覆盖
[cache setObject:newData forKey:@"key"];

// 支持版本控制
NSString *versionedKey = [NSString stringWithFormat:@"key_v%@", version];
[cache setObject:data forKey:versionedKey];

2. 缓存清理机制

YYCache 提供了多种缓存清理机制,包括内存警告自动清理、主动调用清理方法和自定义清理规则。

示例代码:

YYCache *cache = [YYCache cacheWithName:@"ExampleCache"];

// 手动清理缓存
[cache.diskCache removeAllObjects];

// 自定义清理规则
[cache.diskCache trimToCost:1024 * 1024 * 100]; // 保持100MB以内

3. 多线程处理

YYCache 内部使用 GCD 和线程安全的锁机制来保证多线程环境下的缓存操作不会产生竞争条件。

示例代码:

dispatch_queue_t queue = dispatch_queue_create("com.example.cache", DISPATCH_QUEUE_CONCURRENT);

YYCache *cache = [YYCache cacheWithName:@"ExampleCache"];

dispatch_async(queue, ^{
    [cache setObject:data forKey:@"key"];
});

dispatch_async(queue, ^{
    id cachedData = [cache objectForKey:@"key"];
});

4. 持久化策略

YYCache 的缓存数据持久化通过磁盘缓存来实现。所有需要持久化的数据都会被序列化后保存到文件系统中。

示例代码:

YYCache *cache = [YYCache cacheWithName:@"PersistentCache"];

// 设置持久化数据
[cache.diskCache setObject:data forKey:@"key"];

// 获取持久化数据
id cachedData = [cache.diskCache objectForKey:@"key"];

5. 数据压缩与加密(可选)

在需要的时候,可以对缓存的数据进行压缩和加密处理,以提高存储效率和数据安全性。

示例代码:

#import <CommonCrypto/CommonCrypto.h>

// 对数据进行加密
NSData *encryptData(NSData *data, NSString *key) {
    //实现加密逻辑,这里只是示例
    return data;
}

// 对数据进行解密
NSData *decryptData(NSData *data, NSString *key) {
    //实现解密逻辑,这里只是示例
    return data;
}

// 使用 YYCache 进行加密数据缓存
YYCache *secureCache = [YYCache cacheWithName:@"SecureCache"];

- (void)cacheEncryptedData:(NSData *)data forKey:(NSString *)key {
    NSData *encryptedData = encryptData(data, @"encryption_key");
    [secureCache setObject:encryptedData forKey:key];
}

- (NSData *)cachedDecryptedDataForKey:(NSString *)key {
    NSData *cachedData = (NSData *)[secureCache objectForKey:key];
    return decryptData(cachedData, @"encryption_key");
}

总结

YYCache 在 iOS 开发中有着多种应用场景,不仅局限于图片缓存、网络数据缓存和用户会话数据缓存,还包括配置文件缓存、搜索历史缓存、地图数据缓存以及表单数据缓存等。通过深入理解YYCache的底层原理,它的高效性和灵活性在于内存缓存和磁盘缓存的合理搭配、线程安全处理、数据更新策略和持久化策略等。了解和掌握这些细节,可以帮助开发者更好地利用YYCache提升应用性能和用户体验。

标签:缓存,forKey,YYCache,iOS,114,NSString,key,id
From: https://www.cnblogs.com/chglog/p/18307079

相关文章

  • iOS开发基础115-Socket
    在现代网络编程中,Socket(套接字)是实现网络通信的主要机制。Socket提供了端到端的双向通信接口,使得不同主机上的进程能够通过网络直接通信。在iOS开发中,经常需要使用Socket进行网络请求、实时通信(如聊天、游戏等)。以下将详细介绍Socket的概念,并列举iOS开发中常用的三方Socket框架,深......
  • iOS开发基础113-Unity3D
    在iOS项目中接入Unity3D项目可以创建更复杂且互动性强的应用。Unity3D通常用于游戏开发,它可以与原生iOS项目进行集成。以下是详细的步骤和示例代码,且深入讨论其底层原理。步骤1.创建Unity3D项目打开Unity3D并创建一个新项目。完成项目场景和逻辑编写。在Unity3D项目中,设置i......
  • iOS开发基础112-GCD
    GrandCentralDispatch(GCD)在iOS中的常见运用场景GCD是Apple提供的多线程编程技术,旨在提供高效、轻量级的方式来执行并发任务。GCD使得管理线程变得简单且提高了应用程序的性能。以下是GCD在iOS中的一些常见运用场景,并详细介绍其底层原理。1.异步任务处理场景:网络请求使用GCD......
  • iOS开发基础110-Core Graphics应用场景
    CoreGraphics是一种强大的二维图形绘制框架,广泛应用于iOS开发中。以下是几个常见的运用场景以及对应的代码示例:1.自定义视图绘制通过覆盖UIView的drawRect:方法,可以自定义视图的外观。示例代码:#import<UIKit/UIKit.h>@interfaceCustomView:UIView@end@implementat......
  • iOS开发基础109-网络安全
    在iOS开发中,保障应用的网络安全是一个非常重要的环节。以下是一些常见的网络安全措施及对应的示例代码:Swift版1.使用HTTPS确保所有的网络请求使用HTTPS协议,以加密数据传输,防止中间人攻击。示例代码:在Info.plist中配置AppTransportSecurity(ATS):<key>NSAppTransportSecur......
  • iOS开发基础108-常见的编程范式
    1.面向过程编程(Process-OrientedProgramming,POP)代码示例(Swift)importUIKitclassViewController:UIViewController{overridefuncviewDidLoad(){super.viewDidLoad()printGreeting()printNumber(num:42)}/......
  • iOS开发基础107-直播
    在iOS平台上,直播技术已经很成熟,有许多强大的第三方框架可以帮助开发者轻松实现直播功能。当前主流的直播第三方框架包括但不限于:LFLiveKit:一款开源的直播推流SDK。PLMediaStreamingKit:由云天存提供的一站式音视频解决方案。AliyunPlayer:阿里云提供的音视频播放解决方案。A......
  • iOS开发基础105-Xcode收集Crashs的各种方法
    Xcode提供了一整套工具和功能来帮助开发者收集、分析和处理应用崩溃报告。通过这些工具,开发者可以追踪和解析崩溃日志,以更加准确和及时地修复问题。以下是详细介绍Xcode工具收集崩溃报告的各种方法。一、通过设备获取崩溃报告1.连接设备将iOS设备通过USB连接到您的Mac......
  • iOS开发基础106-Instruments
    Instruments是苹果公司提供的一款强大的分析和性能调试工具,集成在Xcode开发环境中。Instruments可帮助开发者分析和优化iOS、macOS应用,检测性能瓶颈、内存泄漏、CPU使用率、磁盘I/O等问题,从而提升应用的效率和用户体验。以下详细介绍Instruments的主要功能和使用方法......
  • iOS开发基础104-正向代理和反向代理
    正向代理和反向代理是计算机网络中两种重要的技术,它们在网络请求的传递和管理上扮演着不同的角色。下面将详细介绍这两者的概念、优缺点,并探讨它们在iOS开发中的应用。一、正向代理1.概念正向代理是一种代理服务器,客户端向代理服务器发送请求,由代理服务器转发请求到目标服务器......