ios开发缓存处理类NSCash类的了解与使用
一:NSCash的基本了解
#import "ViewController.h" @interface ViewController ()<NSCacheDelegate>
/** 注释 */
@property (nonatomic, strong) NSCache *cache;
@end @implementation ViewController -(NSCache *)cache
{
if (_cache == nil) {
_cache = [[NSCache alloc]init];
_cache.totalCostLimit = ;//总成本数是5 ,如果发现存的数据超过中成本那么会自动回收之前的对象(假设有10个成本,totalCostLimit为5,超过5个之后,在最前面创建的成本就会被回收)
_cache.delegate = self;
}
return _cache;
} //存数据:
/**
* 1:NSCache的Key只是对对象进行Strong引用,不是拷贝(和可变字典的区别),而字典是对key进行的拷贝
2:[self.cache setObject:data forKey:@(i) cost:1];const代表成本,若是data的值写在外界,每次得到的都是同一个对象,则总的成本为1,若是在里面每次获得都是新的对象,则所获得总成本为10。也就是10次执行的对象若都是同一个,则成本计算只会为1,若十次得到的都是不同的对象,则总成本为10
*
*/
- (IBAction)addBtnClick:(id)sender
{
//NSCache的Key只是对对象进行Strong引用,不是拷贝(和可变字典的区别)
for (NSInteger i = ; i<; i++) {
NSData *data = [NSData dataWithContentsOfFile:@"/Users/xiaomage/Desktop/Snip20160221_38.png"]; //cost:成本,
[self.cache setObject:data forKey:@(i) cost:];
NSLog(@"存数据%zd",i);
}
} //取数据 /**
* 1:当去取数据的时候或是接受外界传递的参数的时候,严禁一些要进行判断,判断该值是否存在
*
*/
- (IBAction)checkBtnClick:(id)sender
{
NSLog(@"+++++++++++++++");
for (NSInteger i = ; i<; i++) {
NSData *data = [self.cache objectForKey:@(i)];
if (data) {
NSLog(@"取出数据%zd",i);
}
}
} //删除数据
- (IBAction)removeBtnClick:(id)sender
{
[self.cache removeAllObjects];
} #pragma mark ----------------------
#pragma mark NSCacheDelegate
//即将回收对象的时候调用该方法
-(void)cache:(NSCache *)cache willEvictObject:(id)obj
{
NSLog(@"回收%zd",[obj length]);
}
@end
1.SDWebImage相关知识点补充
01.SDWebImage接收到内存警告的时候如何处理?采用监听系统警告通知的方式处理,接收到警告后清空缓存
02.SDWebImage队列最大并发数为6
03.SDWebImage内部设置下载图片超时时间为15m
04.SDWebImage图片下载操作使用了NSURLConnection类发送网络请求实现
05.SDWebImage内部使用NSCache类来进行缓存处理
06.SDWebImage内部如何判断图片类型?判断该图片二进制数据的第一个字节
07.SDWebImage做沙盒缓存时图片的命名机制是拿到图片的URL后直接对URL进行MD5加密
2.NSCache知识点补充
01.NSCache是专门用来进行缓存处理的,
02.NSCache简单介绍:
2-1 NSCache是苹果官方提供的缓存类,具体使用和NSDictionary类似,在AFN和SDWebImage框架中被使用来管理缓存
2-2 苹果官方解释NSCache在系统内存很低时,会自动释放对象(但模拟器演示不会释放)
建议:接收到内存警告时主动调用removeAllObject方法释放对象
2-3 NSCache是线程安全的,在多线程操作中,不需要对NSCache加锁
2-4 NSCache的Key只是对对象进行Strong引用,不是拷贝
03 属性介绍:
name:名称
delegete:设置代理
totalCostLimit:缓存空间的最大总成本,超出上限会自动回收对象。默认值为0,表示没有限制
countLimit:能够缓存的对象的最大数量。默认值为0,表示没有限制
evictsObjectsWithDiscardedContent:标识缓存是否回收废弃的内容
04 方法介绍
- (void)setObject:(ObjectType)obj forKey:(KeyType)key;//在缓存中设置指定键名对应的值,0成本
- (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g;//在缓存中设置指定键名对应的值,并且指定该键值对的成本,用于计算记录在缓存中的所有对象的总成本,出现内存警告或者超出缓存总成本上限的时候,缓存会开启一个回收过程,删除部分元素
- (void)removeObjectForKey:(KeyType)key;//删除缓存中指定键名的对象
- (void)removeAllObjects;//删除缓存中所有的对象
二:NSCash的使用:
#import "ViewController.h"
#import "XMGAPP.h" @interface ViewController ()
/** tableView的数据源 */
@property (nonatomic, strong) NSArray *apps;
/** 内存缓存 */
@property (nonatomic, strong) NSCache *images;
/** 队列 */
@property (nonatomic, strong) NSOperationQueue *queue;
/** 操作缓存 */
@property (nonatomic, strong) NSMutableDictionary *operations;
@end @implementation ViewController #pragma mark ----------------------
#pragma mark lazy loading
-(NSOperationQueue *)queue
{
if (_queue == nil) {
_queue = [[NSOperationQueue alloc]init];
//设置最大并发数
_queue.maxConcurrentOperationCount = ;
}
return _queue;
}
-(NSCache *)images
{
if (_images == nil) {
_images = [[NSCache alloc]init]; //设置最多可以缓存多少个数据
//_images.countLimit = 4;
}
return _images;
}
-(NSArray *)apps
{
if (_apps == nil) { //字典数组
NSArray *arrayM = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"apps.plist" ofType:nil]]; //字典数组---->模型数组
NSMutableArray *arrM = [NSMutableArray array];
for (NSDictionary *dict in arrayM) {
[arrM addObject:[XMGAPP appWithDict:dict]];
}
_apps = arrM;
}
return _apps;
} -(NSMutableDictionary *)operations
{
if (_operations == nil) {
_operations = [NSMutableDictionary dictionary];
}
return _operations;
} #pragma mark ----------------------
#pragma mark UITableViewDatasource
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return ;
} -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.apps.count;
} -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ID = @"app"; //1.创建cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; //2.设置cell的数据
//2.1 拿到该行cell对应的数据
XMGAPP *appM = self.apps[indexPath.row]; //2.2 设置标题
cell.textLabel.text = appM.name; //2.3 设置子标题
cell.detailTextLabel.text = appM.download; //2.4 设置图标 //先去查看内存缓存中该图片时候已经存在,如果存在那么久直接拿来用,否则去检查磁盘缓存
//如果有磁盘缓存,那么保存一份到内存,设置图片,否则就直接下载
//1)没有下载过
//2)重新打开程序 UIImage *image = [self.images objectForKey:appM.icon];
if (image) {
cell.imageView.image = image;
NSLog(@"%zd处的图片使用了内存缓存中的图片",indexPath.row) ;
}else
{
//保存图片到沙盒缓存
NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
//获得图片的名称,不能包含/
NSString *fileName = [appM.icon lastPathComponent];
//拼接图片的全路径
NSString *fullPath = [caches stringByAppendingPathComponent:fileName]; //检查磁盘缓存
NSData *imageData = [NSData dataWithContentsOfFile:fullPath];
//废除
imageData = nil; if (imageData) {
UIImage *image = [UIImage imageWithData:imageData];
cell.imageView.image = image; NSLog(@"%zd处的图片使用了磁盘缓存中的图片",indexPath.row) ;
//把图片保存到内存缓存
[self.images setObject:image forKey:appM.icon]; // NSLog(@"%@",fullPath);
}else
{
//检查该图片时候正在下载,如果是那么久什么都捕捉,否则再添加下载任务
NSBlockOperation *download = [self.operations objectForKey:appM.icon];
if (download) { }else
{ //先清空cell原来的图片
cell.imageView.image = [UIImage imageNamed:@"Snip20160221_306"]; download = [NSBlockOperation blockOperationWithBlock:^{
NSURL *url = [NSURL URLWithString:appM.icon];
NSData *imageData = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:imageData]; NSLog(@"%zd--下载---",indexPath.row); //容错处理
if (image == nil) {
[self.operations removeObjectForKey:appM.icon];
return ;
}
//演示网速慢的情况
//[NSThread sleepForTimeInterval:3.0]; //把图片保存到内存缓存
[self.images setObject:image forKey:appM.icon]; //NSLog(@"Download---%@",[NSThread currentThread]);
//线程间通信
[[NSOperationQueue mainQueue] addOperationWithBlock:^{ //cell.imageView.image = image;
//刷新一行
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
//NSLog(@"UI---%@",[NSThread currentThread]);
}]; //写数据到沙盒
[imageData writeToFile:fullPath atomically:YES]; //移除图片的下载操作
[self.operations removeObjectForKey:appM.icon]; }]; //添加操作到操作缓存中
[self.operations setObject:download forKey:appM.icon]; //添加操作到队列中
[self.queue addOperation:download];
} }
} //3.返回cell
return cell;
} #pragma mark ----------------------
#pragma mark UITableViewDelegate
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{ NSArray *arrayM = self.apps;
//检查缓存数据
for (NSInteger i = ; i < arrayM.count; i++) {
XMGAPP *appM = arrayM[i]; UIImage *image = [self.images objectForKey:appM.icon];
if (image) {
NSLog(@"存在图片缓存%zd",i);
}
}
} -(void)didReceiveMemoryWarning
{
[self.images removeAllObjects]; //取消队列中所有的操作
[self.queue cancelAllOperations];
} //1.UI很不流畅 --- > 开子线程下载图片
//2.图片重复下载 ---> 先把之前已经下载的图片保存起来(字典)
//内存缓存--->磁盘缓存 //3.图片不会刷新--->刷新某行
//4.图片重复下载(图片下载需要时间,当图片还未完全下载之前,又要重新显示该图片)
//5.数据错乱 ---设置占位图片 /*
Documents:会备份,不允许
Libray
Preferences:偏好设置 保存账号
caches:缓存文件
tmp:临时路径(随时会被删除)
*/ @end
ios开发缓存处理类NSCash类的了解与使用的更多相关文章
- iOS开发笔记系列-基础2(类)
面向对象编程总是离不开类和对象的,Objective-C也不例外,不过Objective-C中的类还有一些自己的独特点. 类的声明和定义 在iOS开发中,类的声明与定义通常都是分开的,类得声明通常存放 ...
- 【IOS 开发】Object - C 面向对象 - 类 , 对象 , 成员变量 , 成员方法
. 一. 类定义 类定义需要实现两部分 : -- 接口部分 : 定义类的成员变量和方法, 方法是抽象的, 在头文件中定义; -- 实现部分 : 引入接口部分的头文件, 实现抽象方法; 1. 接口部分定 ...
- IOS开发之网络编程开源类 Reachability应用
先看Reachability.h发现 #import <Foundation/Foundation.h> #import <SystemConfiguration/SystemCon ...
- iOS开发——项目实战OC篇&类QQ黏性按钮(封装)
类QQ粘性按钮(封装) 那个,先来说说原理吧: 这里原理就是,在界面设置两个控件一个按钮在上面,一个View在下面(同样大小),当我们拖动按钮的时候显示下面的View,view不移动,但是会根据按钮中 ...
- iOS开发之音频播放AVAudioPlayer 类的介绍
主要提供以下了几种播放音频的方法: 1. System Sound Services System Sound Services是最底层也是最简单的声音播放服务,调用 AudioServicesPla ...
- iOS开发--音乐文件播放工具类的封装(包含了音效的封装)
一.头文件 #import <Foundation/Foundation.h> #import <AVFoundation/AVFoundation.h> @interface ...
- IOS开发缓存机制之—本地缓存机制
功能需求 这个缓存机制满足下面这些功能. 1.可以将数据缓存到本地磁盘. 2.可以判断一个资源是否已经被缓存.如果已经被缓存,在请求相同的资源,先到本地磁盘搜索. 3.可以判断文件缓存什么时候过期.这 ...
- iOS开发之使用Runtime给Model类赋值
本篇博客算是给网络缓存打个基础吧,本篇博客先给出简单也是最容易使用的把字典转成实体类的方法,然后在给出如何使用Runtime来给Model实体类赋值.本篇博客会介绍一部分,主要是字典的key与Mode ...
- iOS开发之遍历Model类的属性并完善使用Runtime给Model类赋值
在上篇博客<iOS开发之使用Runtime给Model类赋值>中介绍了如何使用运行时在实体类的基类中添加给实体类的属性赋值的方法,这个方法的前提是字典的Key必须和实体类的Property ...
随机推荐
- UVa10397_Connect the Campus(最小生成树)(小白书图论专题)
解题报告 题目传送门 题意: 使得学校网络互通的最小花费,一些楼的线路已经有了. 思路: 存在的线路当然全都利用那样花费肯定最小,把存在的线路当成花费0,求最小生成树 #include <ios ...
- hdu 1003 Max Sum 最大字段和 dp
今天看了一上午dp.看不太懂啊.dp确实不简单.今天開始学习dp,搜了杭电的dp46道,慢慢来吧.白书上的写的 又不太具体,先写几道题目再说. .. 题目连接:id=516&page=1&qu ...
- HDU 1495 很可乐(BFS 倒水问题)
题意 将体积为s的可乐 利用容积分别为n和m的两个杯子平均分为两份 至少须要倒多少次可乐 能够把容器s,n,m中装的可乐量看成一种状态 容器都是没有刻度的 所以每次倒可乐要么把自己倒完 要么把 ...
- Spark通过YARN提交任务不成功(包含YARN cluster和YARN client)
无论用YARN cluster和YARN client来跑,均会出现如下问题. [spark@master spark-1.6.1-bin-hadoop2.6]$ jps 2049 NameNode ...
- shiro session管理
http://shiro.apache.org/session-management.html Using Sessions The SessionManager Session Timeout Pe ...
- iTOP-4412 nfs文件系统启动
kernel command line type: 普通文件系统(本地)启动:root=/dev/mmcblk0p2 rootfstype=ext4 init=/linuxrc console=tty ...
- l洛谷 P3926 SAC E#1 - 一道不可做题 Jelly
P3926 SAC E#1 - 一道不可做题 Jelly 题目背景 SOL君(炉石主播)和SOL菌(完美信息教室讲师)是好朋友. 题目描述 SOL君很喜欢吃蒟蒻果冻.而SOL菌也很喜欢蒟蒻果冻. 有一 ...
- Linux下常用的中文输入法平台有IBus、fcitx和scim
Linux下常用的中文输入法平台有IBus.fcitx和scim.scim现在维护滞后,不推荐使用. IBus ("Intelligent Input Bus") 是一个 输入法框 ...
- JS 保留2位小数 四舍五入(小数点后面不足2位,自动用0补齐)
function changeTwoDecimal_f(x) { var f_x = parseFloat(x); if (isNaN(f_x)) { alert('function:changeTw ...
- Quick Sort Algorithm
快速排序算法实现代码: //============================================================================ // Name : ...