美文网首页EntryTask
LRU在iOS中的实现

LRU在iOS中的实现

作者: Miracle_任 | 来源:发表于2022-04-15 16:57 被阅读0次

    LRU是一种缓存淘汰算法,是一种缓存淘汰机制

    具体原理不做赘述,这里只提供实现示例。

    *目前只实现了Swift&OC版本,后续会更新双链表等实现方法。
    Swift代码示例:

    //
    //  LRUCache.swift
    //  LRU缓存工具类
    //  本类只是实现LRU思路,并没有进行真正意义的本地缓存数据。具体采用什么方式进行本地缓存,请自行添加。
    //  Created by Miracle on 2022/4/15.
    //
    
    
    import UIKit
    
    class LRUCache: NSObject {
    
        static let shared = LRUCache()
        
        
        // MARK: 私有属性
        
        
        /// 最大数量
        private var maxCount: Int = 0
        
        /// 存放key的数组
        private var keysArr: [String] = [String]()
        
        /// 存放数据的字典
        private var dataDic: [String:Any] = [String:Any]()
        
        
        // MARK: 公开方法
        
        /// 创建/重置方法
        /// - Parameter maxCount: 最大缓存数量
        func initOrReset(maxCount: Int) {
            
            //赋值最大缓存数量
            self.maxCount = maxCount
            
            //清空记录的内容
            keysArr.removeAll()
            dataDic.removeAll()
        }
        
        
        /// 增加数据缓存方法
        /// - Parameters:
        ///   - value: 数据
        ///   - key: key
        func add(value: Any, key: String) {
            
            //是否已经存在了
            let isExist = keysArr.contains(key) && dataDic.keys.contains(key)
            
            //存数据
            dataDic[key] = value
            
            //将key移动到最前面
            if isExist {
                moveToHeader(key: key)
            } else {
                keysArr.insert(key, at: 0)
            }
            
            //超出最大缓存限制,删除末位数据
            if keysArr.count > maxCount {
                let removeKey = keysArr.last ?? ""
                remove(key: removeKey)
            }
        }
        
        
        /// 根据key删除缓存数据
        func remove(key: String) {
            
            //移除数据字典中的对应数据
            if dataDic.keys.contains(key) {
                dataDic.removeValue(forKey: key)
            }
            
            //移除key数组中的key
            if keysArr.contains(key) {
                keysArr.removeAll(){
                    $0 == key
                }
            }
        }
        
        
        /// 根据key获取数据
        func getData(key: String) -> Any {
            
            //根据key取数据
            let data = dataDic[key] as Any
            
            //将key移动到最前面
            moveToHeader(key: key)
            
            return data
        }
        
        
        // MARK: 私有方法
        
        
        /// 将key移动到最前面
        /// - Parameter key: 数据key
        private func moveToHeader(key: String) {
            
            //不包含直接返回
            if !keysArr.contains(key) {
                return
            }
            
            //移除对应的key
            keysArr.removeAll(){
                $0 == key
            }
            
            //将key添加到第0个
            keysArr.insert(key, at: 0)
        }
        
    }
    
    

    OC代码示例:
    LRUCache-OC.h

    //
    //  LRUCache-OC.h
    //  LRU缓存工具类
    //  本类只是实现LRU思路,并没有进行真正意义的本地缓存数据。具体采用什么方式进行本地缓存,请自行添加。
    //  Created by Miracle on 2022/4/20.
    //
    
    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface LRUCache_OC : NSObject
    
    +(instancetype)shard;
    
    /// 创建/重置方法
    /// @param maxCount 最大缓存数量
    -(void)initOrResetWithMaxCount:(int)maxCount;
    
    /// 添加缓存
    -(void)addWithKey:(NSString *)key value:(id)value;
    
    /// 根据key删除数据
    -(void)removeWithKey:(NSString *)key;
    
    /// 根据key获取数据
    -(id)getDataWithKey:(NSString *)key;
    @end
    
    NS_ASSUME_NONNULL_END
    
    

    LRUCache-OC.m

    //
    //  LRUCache-OC.m
    //  LRU缓存工具类
    //  本类只是实现LRU思路,并没有进行真正意义的本地缓存数据。具体采用什么方式进行本地缓存,请自行添加。
    //  Created by Miracle on 2022/4/20.
    //
    
    #import "LRUCache-OC.h"
    
    @interface LRUCache_OC()
    
    /// 最大数量
    @property(nonatomic,assign) int maxCount;
    
    /// 存放key的数组
    @property(nonatomic,strong) NSMutableArray * keysArr;
    
    /// 存放数据的字典
    @property(nonatomic,strong) NSMutableDictionary * dataDic;
    
    @end
    
    @implementation LRUCache_OC
    
    
    +(instancetype)shard{
        
        static LRUCache_OC * _shard;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _shard = [[[self class] alloc] init];
        });
        return _shard;
    }
    
    
    /// 创建/重置方法
    /// @param maxCount 最大缓存数量
    -(void)initOrResetWithMaxCount:(int)maxCount{
        
        self.maxCount = maxCount;
        self.keysArr = [[NSMutableArray alloc]initWithCapacity:0];
        self.dataDic = [[NSMutableDictionary alloc]initWithCapacity:0];
    }
    
    /// 添加缓存
    -(void)addWithKey:(NSString *)key value:(id)value{
        
        //是否已经存在了
        BOOL isExist = [self.keysArr containsObject:key] && [self.dataDic.allKeys containsObject:key];
        
        //存数据
        [self.dataDic setValue:value forKey:key];
        
        //将key移动到最前面
        if (isExist) {
            [self moveToHeaderForKey:key];
        } else {
            [self.keysArr insertObject:key atIndex:0];
        }
        
        //超出最大限制,删除末位数据
        if (self.keysArr.count > self.maxCount) {
            NSString * lastKey = self.keysArr.lastObject;
            [self removeWithKey:lastKey];
        }
    }
    
    
    /// 将key移动到最前面
    -(void)moveToHeaderForKey:(NSString *)key{
        
        //如果不包含,直接返回
        if (![self.keysArr containsObject:key]) {
            return;
        }
        
        [self.keysArr removeObject:key];
        [self.keysArr insertObject:key atIndex:0];
    }
    
    
    /// 根据key删除数据
    -(void)removeWithKey:(NSString *)key{
        
        if ([self.dataDic.allKeys containsObject:key]) {
            [self.dataDic removeObjectForKey:key];
        }
        
        if ([self.keysArr containsObject:key]) {
            [self.keysArr removeObject:key];
        }
    }
    
    
    /// 根据key获取数据
    -(id)getDataWithKey:(NSString *)key{
        
        id data = [self.dataDic objectForKey:key];
        
        [self moveToHeaderForKey:key];
        
        return data;
    }
    
    
    @end
    
    

    github链接

    相关文章

      网友评论

        本文标题:LRU在iOS中的实现

        本文链接:https://www.haomeiwen.com/subject/hmrqertx.html