OSChina_IOS版客户端笔记(四)_程序数据、缓存的管理
为什么80%的码农都做不了架构师?>>>
程序的数据缓存问题。首先常见的程序数据可以分为以下几种:
· 列表、表格等在线请求的动态数据
· 图片数据,可以是列表中在线请求的
· 用户信息、程序设置、程序版本信息等
列表数据的缓存:
观察OSChina的iOS版发现,每次切换UISegmentController后都会进行数据的在线请求,而没有使用缓存数据(也可能是有某个代码开关本人没看清楚吧)。总之这篇文章也不是基于OSChina的iOS客户端的,而是从博主目前已完成的一个项目中抽取出来的。功能要求:
1.由于列表包含了下拉刷新功能,所以在每次切换UISegment时,不进行数据的在线请求,直接使用缓存数据,用户手动拖动列表触发下拉刷新时,才进行数据的在线更新(先清空原本所有的缓存文件,在从第一页开始重新缓存)
2.如果某个页面还没有进行数据缓存,那么此时我们也就没有缓存数据可用了,必须进行数据的在线请求。这种情况通常在程序第一次安装时发生。
这里以Json格式的列表数据为例子,讨论一下实现细节:
以下是缓存数据到本地缓存文件的代码
BOOL isDir = NO;BOOL existed = [fm fileExistsAtPath:cacheDir isDirectory:&isDir];if (isDir == YES && existed == YES){[fm removeItemAtPath:cacheDir error:nil];}[fm createDirectoryAtPath:cacheDir withIntermediateDirectories:YES attributes:nil error:nil];[fm createFileAtPath:Json_path contents:nil attributes:nil];NSString *Json_path=[self.cacheDir stringByAppendingPathComponent:fileName];[[responseJsonDic JSONString]writeToFile:Json_path atomically:YES encoding:NSUTF8StringEncoding error:nil];
首先检查了文件是否存在,如果不存在则先创建,在使用[JSONKit writeToFile:atomically:encoding:error]方法来讲Json数据写到缓存文件。
以下是从缓存文件中读取数据的代码
NSDictionary * JSON = [jsonStr objectFromJSONString];
NSDictionary * classMap = [[NSDictionary alloc]initWithObjectsAndKeys:NSStringFromClass(clazz),@"result", nil];
JsonBean * obj =[(NSDictionary *)JSON convertDicToObject:NSStringFromClass([JsonBean class]) classMap:classMap];
[self.dataArray addObjectsFromArray:obj.result];
使用了第三方Json解析工具JSONKit,其中jsonStr是服务器数据,classMap是从Json节点到实体类的映射。clazz是要转换的实体类的class。
整理一下流程:
完整方法:
- (void) refreshTable
{NSString * stringlev = [MyKeyChainHelper getUserLevelWithService:[MyKeyChainHelper getUserLevelKeyString]];NSInteger integerlev = [stringlev integerValue]<0?0:[stringlev integerValue];if (integerlev<self.spinner.grande_code) {UIAlertView * uv = [[UIAlertView alloc]initWithTitle:@"温馨提示" message:@"对不起,您的访问权限不足!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];[uv show];return;}if ([self.spinner.channelId isEqualToString:@"栏目指引"]) {[dataArray removeAllObjects];[dataArray addObject:@"栏目指引1"];[dataArray addObject:@"栏目指引2"];[dataArray addObject:@"栏目指引3"];[self refreshTableComplete];return;}isLastPage = NO;pageNumber=1;NSNumber *startIndex = [[NSNumber alloc]initWithInteger:1];NSString * fileName = [[NSString stringWithFormat:@"pageSize:%lu_startIndex:%@",(long)self.pageSize,startIndex]md5];NSString *Json_path=[self.cacheDir stringByAppendingPathComponent:fileName];BOOL fileExist = [fm fileExistsAtPath:Json_path];if (isFirstRefresh&&fileExist) {//isFirstRefresh表示初次载入界面,fileExist标示着缓存文件是否存在[pullTableDelegate startLoadData];NSError * error;NSString * jsonStr = [NSString stringWithContentsOfFile:Json_path encoding:NSUTF8StringEncoding error:&error];if (error) {}else{NSDictionary * JSON = [jsonStr objectFromJSONString];NSDictionary * classMap = [[NSDictionary alloc]initWithObjectsAndKeys:NSStringFromClass(clazz),@"result", nil];JsonBean * obj =[(NSDictionary *)JSON convertDicToObject:NSStringFromClass([JsonBean class]) classMap:classMap];[self.dataArray removeAllObjects];[self.dataArray addObjectsFromArray:obj.result];self.totalCount = obj.totalCount;if (self.totalCount<=self.pageSize) {isLastPage = YES;}//如果读取到的数据长度为零,则显示"栏目为空"提示页面if([obj.result count] == 0) {[self addSubview:emptyView];}}[self refreshTableComplete];}else{if (![NetUtils isNetWorkConnected]) {[self refreshTableComplete];return;}if (isFirstRefresh) {[[CustomPopView shardInstance] show:@"reload" andMsg:@"数据加载中..." canAnimate:YES];[pullTableDelegate startLoadData];}[self.params setValue:startIndex forKey:@"startIndex"];[self.params setValue:[[NSNumber alloc]initWithInteger:self.pageSize] forKey:@"pageCount"];[HttpClient postWithBlock:self.url listClass:clazz params:self.params block:^(NSDictionary *responseJsonDic, NSError *error) {if (error) {} else {NSDictionary * classMap = [[NSDictionary alloc]initWithObjectsAndKeys:NSStringFromClass(clazz),@"result", nil];JsonBean * obj =[responseJsonDic convertDicToObject:NSStringFromClass([JsonBean class]) classMap:classMap];NSInteger code = obj.code;if (code==0) {[self.dataArray removeAllObjects];[self.dataArray addObjectsFromArray: [[NSMutableArray alloc]initWithArray:obj.result]];self.totalCount = obj.totalCount;if (self.totalCount<=self.pageSize) {isLastPage = YES;}//当栏目数据为空时,显示提示页面if([obj.result count] == 0) {[self addSubview:emptyView];[[CustomPopView shardInstance]hide];}else{BOOL isDir = NO;BOOL existed = [fm fileExistsAtPath:cacheDir isDirectory:&isDir];if (isDir == YES && existed == YES){[fm removeItemAtPath:cacheDir error:nil];}[fm createDirectoryAtPath:cacheDir withIntermediateDirectories:YES attributes:nil error:nil];[fm createFileAtPath:Json_path contents:nil attributes:nil];NSString *Json_path=[self.cacheDir stringByAppendingPathComponent:fileName];[[responseJsonDic JSONString]writeToFile:Json_path atomically:YES encoding:NSUTF8StringEncoding error:nil];}}else{UIAlertView * uv = [[UIAlertView alloc]initWithTitle:@"BaseTableViewCotroller_refreshTable_Error" message:obj.message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];[uv show];}}[self performSelector:@selector(refreshTableComplete) withObject:nil afterDelay:1];}];}
}
本地缓存文件:
图片数据的缓存:
图片数据的缓存是通过一些第三方开源库实现的,比如博主目前使用的SDWebImage,OSChina客户端中使用的EGOImageLoading等。这些只需要耐心的看下文档接口就好了。如果使用SDWebImage的话,目前博主使用的版本是不能在进行数据缓存之前进行缓存尺寸的设置的,为此博主写了为SDImageView写了一个简单的Category,详见:SDWebImage指定缓存图片大小
用户信息、程序信息等
稍微扯一下,博主知道的保存这些数据的方法有UserDefault和KeyChain,KeyChain是加密过的,所以博主现在项目中保存用户信息的是KeyChain,但是KeyChain是存在于系统中的,即卸载完程序后,并不会清除KeyChain数据。必须确保能够在重新安装时可以清空,那么博主的做法是结合UserDefault和KeyChain。在UserDefault中置一个变量用来表示程序是否为初次启动。在程序启动是加以判断,如果是初次启动的话,清除所有存在的KeyChain值。这样就可以解决KeyChain的值在程序初次安装时得以还原。
O啦~~~
转载请求保留出处:http://blog.csdn.net/u011638883/article/details/16979133
谢谢!!
转载于:https://my.oschina.net/cjkall/blog/195810
OSChina_IOS版客户端笔记(四)_程序数据、缓存的管理相关推荐
- ASP.NET缓存全解析4:应用程序数据缓存(转)
ASP.NET缓存全解析文章索引 ASP.NET缓存全解析1:缓存的概述 ASP.NET缓存全解析2:页面输出缓存 ASP.NET缓存全解析3:页面局部缓存 ASP.NET缓存全解析4:应用程序数据缓 ...
- 微信小程序数据缓存Storage
1.存放数据 wx.setStorage(Object object) 将数据存储在本地缓存中指定的 key 中.会覆盖掉原来该 key 对应的内容.数据存储生命周期跟小程序本身一致,即除用户主动删除 ...
- 微信小程序—数据缓存
每个微信小程序都可以有自己的本地缓存,可以通过 wx.setStorag(wx.setStorageSync).wx.getStorage(wx.getStorageSync).wx.clearSto ...
- MySQL学习笔记——第3章 数据表的管理和表中数据操纵
第3章 数据表的管理和表中数据操纵 3.1 MySQL数据类型 数字类型:数字类型包括整数类型和数值类型 整数类型:TINYINT.SMALLINT.MEDIUMINT.INT和BIGINT 数值类型 ...
- 微信小程序数据缓存API整理
1.wx.getStorage(OBJECT) 从本地缓存中异步获取指定 key 对应的内容 wx.getStorage({key: 'key',success: function(res) {con ...
- 美服疯狂坦克辅助瞄准外挂C#版开发(四)程序使用说明和完成源代码及其下载
到现在为止,我们已经将疯狂坦克外挂所需相关的功能点及解决方案完成. 先说说常规的使用方法: 1.编译发布程序后,先运行程序(默认不可见),然后进入美服疯狂坦克. 2.在游戏中按(Pause)键启动各种 ...
- 人大版统计学教材第六版学习笔记--第3章 数据的图表展示
合理使用图表描述统计结果是应用统计的基本技能之一. 文章目录 数据的预处理 数据审核 数据筛选 数据排序 数据透视表 定性数据的整理与展示 分类数据的整理与图示 数据的整理与计算 分类数据的图示 顺序 ...
- c++ primer 第五版 阅读笔记四
第四章 复合类型 4.1 数组 数组的声明:关于数组的内容写了蛮多的,包括一维数组和二维数组的创建.调用.返回等等,甚至用到了static和new/delete关键字,详见:(一维数组相关内容)htt ...
- 蓝牙学习笔记(四)——AC692x程序烧录
程序烧录 下载连接工具 使用双端公对公USB线连接配套的强制下载工具,烧录时需要按下强制工具开关等到蓝灯灭,只有红灯亮的时候可以开始进行程序烧录(此时写入口供电). 加入密钥 在提供的SDK中 ...
最新文章
- spring cloud 断路器仪表盘详解
- 人工智能十大流行算法
- oracle数据库查询open_cursors值的sql语句,达梦数据库查询MAX_SESSION_STATEMENT值方法,MAX_SESSION_STATEMENT的最大值、上限是多少
- dynamic_debug动态打印kernel日志
- SaaS模式云数据仓库:持续保护云上数据及服务安全
- 华为零售商品识别一等奖方案
- Xcode 高级调试技巧
- 计算机如何做材料的应力应变曲线,常用材料应力应变曲线.xlsx
- 最新STM32G0系列选型表1
- WINDOW端口查看命令
- 20200528-换脸算法调研
- 5G UE — USIM Card
- Linux网络编程-七
- 战略项目——科龙空调中高层干部培训记
- 电脑无法安装软件打不开计算机,电脑刚安装软件打不开怎么办
- 什么是安拆网?安拆网有什么作用?
- Linux iptables nat 实现不同网络间(内外网)的互联
- 一文读透GO语言的通道
- flutter中compute和isolate
- 2021年10月管理体系认证基础考试真题试卷
热门文章
- 如何创建一个FeatureClass,IFeatureWorkspace 接口漫谈
- 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十三║Vue实战:Vuex 其实很简单
- Intelligent Factorial Factorization LightOJ - 1035(水题)
- List中toArray()的使用方法
- 深入浅出学习Hibernate框架(一):从实例入手初识Hibernate框架
- CG-CTF-Web-AAencode
- ubuntu切换JDK版本
- python字符串title函数_python字符串内建函数-capitalize、title、upper
- mysql连接报错:Unknown system variable ‘query_cache_size‘
- vue动态生成表单元素基础篇