iOS SDWebImgae Cache原理

weixin_33913332發表於2019-02-22

寫這篇文章的原因,作為開發者也有好幾年了,曾有對著名第三方SDWebImgae做一個簡單的研究,今天就把當初研究寫的Demo和原理分享給大家,面試曾遇到過哦~

一、建立一個繼承NSObject的工具類DownImageManager

點h實現

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface DownImageManager : NSObject
{
    //建立一個記憶體字典
    NSMutableDictionary * _memoryDict;
    
}
//建立一個單例類

+(DownImageManager *)shareManager;


//從記憶體中找
-(UIImage *)getImageFromMemoryWithUrl:(NSString *)urlStr;
//從沙盒中找
-(UIImage *)getImageFromSendBoxWithUrl:(NSString *)urlStr;

//網路下載
-(void)downImageFromNetWorkWithUrl:(NSString *)url imageView:(UIImageView *)imageView;



@end

點m實現

#import "NSString+Addtions.h"
#import "Base64.h"
DownImageManager * _downManager;

//NSOperationQueue * queue;

@implementation DownImageManager


#pragma mark -------只初始化一次,單例列
+(DownImageManager *)shareManager{
    
    
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        _downManager = [[DownImageManager alloc]init];
    });
    return _downManager;
    
}
//返回當前類的物件instancetype
-(instancetype)init{
    
    self= [super init];
    if (self) {
        _memoryDict = [[NSMutableDictionary alloc ]init];
    }
    return self;
}
//存到記憶體
-(UIImage *)getImageFromMemoryWithUrl:(NSString *)urlStr{

    UIImage *image = _memoryDict[urlStr];
    
    return image;
}
//存到沙盒資料夾下
-(UIImage *)getImageFromSendBoxWithUrl:(NSString *)urlStr{
    
    NSString * path = [NSString getFilePathWithDir:@"Documents/huangshiwen" file:[urlStr base64EncodedString]];
    
    //從沙盒資料夾下找圖片
    UIImage *image= [UIImage imageWithContentsOfFile:path];
    
    //如果有圖片就存起來
    if (image) {
        [_memoryDict setObject:image forKey:urlStr];
    }
    return  image;
}

//網路下載
-(void)downImageFromNetWorkWithUrl:(NSString *)url imageView:(UIImageView *)imageView{
    
    NSDictionary * dict =@{@"url":url,@"imageView":imageView};
    
    NSInvocationOperation * operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(loadImage:) object:dict];
    
    NSOperationQueue * queue = [[NSOperationQueue alloc]init];
    //執行
    [queue addOperation:operation];
    
    
}
-(void)loadImage:(NSDictionary *)dict{
    
    //從字典找鍵值對(圖片 網址 )
    
    NSURL *url = [NSURL URLWithString:dict[@"url"]];
    
    UIImageView *imageView = dict[@"imageView"];
    
    //開始轉換
    
    NSData * data =[NSData dataWithContentsOfURL:url];
    UIImage * image = [UIImage imageWithData:data];
    
    //開始回到主執行緒重新整理ui
    dispatch_async(dispatch_get_main_queue(), ^{
        //如果下載好了
        if (image) {
             //存入記憶體字典
            [_memoryDict setObject:image forKey:dict[@"url"]];
            //存入沙盒檔案
            NSString *path = [NSString getFilePathWithDir:@"Documents/huangshiwen" file:[dict[@"url"] base64EncodedString]];
            
            //資料持久化儲存
            [data writeToFile:path atomically:YES];
            
            //顯示
            imageView.image = image;
            
        }
    });
 
}
@end

二、新建一個UIImageView的category (UIImageView+Addtition.h)

#import <UIKit/UIKit.h>

@interface UIImageView (Addtition)


//擴充套件類方法
-(void)setImageWithUrl:(NSString *)urlStr;

//
-(void)setimageWithUrl:(NSString *)urlStr placeHolderImage:(UIImageView *)image;


@end

#import "UIImageView+Addtition.h"
#import "DownImageManager.h"
@implementation UIImageView (Addtition)

#pragma mark --------imageUrl
-(void)setImageWithUrl:(NSString *)urlStr{
    
 DownImageManager * manager  = [DownImageManager shareManager];
    
    UIImage * image = [manager getImageFromMemoryWithUrl:urlStr];
    
   
    
    
    //存在記憶體
    if (image) {
        self.image= image;
        return;
    }
    //本地沙盒
    image = [manager getImageFromSendBoxWithUrl:urlStr];
    if (image) {
        self.image=image;
        return;
    }
    //載入網路
//    self 當前呼叫這個方法的物件(當前類的物件)
    
    [manager downImageFromNetWorkWithUrl:urlStr imageView:self];
    
}


#pragma mark ========佔點陣圖
-(void)setimageWithUrl:(NSString *)urlStr placeHolderImage:(UIImage *)image{
    
    self.image =image;
    [self setImageWithUrl:urlStr];
    
}
@end

三、使用


- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self.imageView1 setImageWithUrl:@"http://video.rednet.cn/uploadfile/2015/0311/20150311111749232.jpg"];
    
    
    [self.imageView2 setimageWithUrl:@"http://video.rednet.cn/uploadfile/2015/0311/20150311111749232.jpg" placeHolderImage:nil];
    
}

總結:

1911628-cb2cb0f581d4d2ce.png
SDWebImage原理

相關文章