前言:
为什么使用缓存,最直观的优势在于用户使用APP的体验上。举一个场景例子,比如现如今市面上的新闻应用,用户上了地铁或者走到一个网络信号极端差的区域,此刻尴尬的局面出现,因为没有网络,导致应用不能反馈给用户任何信息,作为用户的你是不是有种焦急不安的烦躁,想立刻删除应用的冲动,慢着今天的主角缓存来也,他将瞬间弥补此刻的尴尬,为什么这么说,用户了解自己的生活环境,他知道哪些区域网络的卡顿,在网络卡顿之前首先缓存一部分自己关注的东西在手机上,就算遇到没有网络的情况,手机照样能及时显示用户关心的数据。好了闲话到此打住,开始进入我们今天的主题"缓存"。
IOS中缓存技术了解
- CoreData:CoreData技术其实是苹果对Sqlite数据库操作进行的封装,Sqlite是一款小型数据库,因为安装方便体积小被广发应用到移动平台,在移动平台主要担任处理逻辑较为复杂的数据集,但在真实开发中操作步骤相比其他技术较为复杂,所以开发中应用的不是太过于广泛。
- Plist文件:通过对plist文件读写操作,将数据存储,底下的NSUserDefualt以及NSCoding技术的底层实现就是通过对plist多层封装而达到的效果,plist的弊端就是数据量小,而且对于频率操作增删改查就有点不是很擅长。
- NSUserDefault:用户偏好设置,因操作灵活语法简练,两行代码便能完成存储数据的操作,一般可以存储系统中常见对象,例如: NSString,NSArray,NSDictionary,int,BOOL...因此被开发者们追捧,但其弊端也不可小视,不能存储模型对象,而且存储量小,所以只能被小范围使用。
- NSCoding:目前比较主流的缓存技术,可以说他弥补了NSUserDefault所带来的缺失,但是有一点必须注意,如果数据量特别大(上万条数据),那么还是请使用CoreData技术实现比较好。
实际操作
备注:因为Sqlite相对操作复杂,我们把它放到最后去讲解。
- 我们看下Plist文件的读写操作:
/**
* 读出数据
*
* @param plistName plist文件
*
* @return 取出的数据
*/
+ (__kindof NSArray *)getDataWithPlistName:(NSString *)plistName
{
// 1.拿到沙盒中的Documents目录
NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [docPaths objectAtIndex:0];
// 2.拼接需要操作文件的路径
NSString *filePath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist",plistName]];
// 3.返回数据
return [NSArray arrayWithContentsOfFile:filePath];
}
/**
* 写数据到plist文件上
*
* @param plistName plist 文件名
* @param data 存储的数据(系统对象都能存储,存储的数据都会默认放在数组里)
* @param successBlock 文件创建成功
* @param errorBlock 文件创建失败
*/
+ (void)writeDataWithPlistName:(NSString *)plistName
withData:(id)data
withSuccessBlock:(void(^)(NSString *))successBlock
withErrorBlock:(void(^)(NSString *))errorBlock
{
// 1.拿到沙盒中的Documents目录
NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [docPaths objectAtIndex:0];
// 2.拼接需要操作文件的路径
NSString *filePath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist",plistName]];
// 3.准备数据
NSArray *testDataArray = @[data];
// 4.创建文件
NSFileManager *fm = [NSFileManager defaultManager];
if ([fm createFileAtPath:filePath contents:nil attributes:nil]) {
// 5.写数据到plist文件
[testDataArray writeToFile:filePath atomically:YES];
successBlock(@"文件创建成功");
}else{
errorBlock(@"文件创建失败");
}
}
- 我们再看下UserDefault存储
// 偏好设置值
- (void)getUserDefault
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSLog(@"str-->%@",[ud objectForKey:@"str"]);
NSLog(@"integer-->%tu",[ud integerForKey:@"integer"]);
NSLog(@"bool-->%d",[ud boolForKey:@"bool"]);
NSLog(@"float-->%f",[ud floatForKey:@"float"]);
NSLog(@"double-->%f",[ud doubleForKey:@"double"]);
NSLog(@"value-->%@",[ud valueForKey:@"value"]);
NSLog(@"url-->%@",[ud URLForKey:@"url"]);
}
// 偏好设置值
- (void)setUserDefault
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[ud setObject:@"NSString" forKey:@"str"];
[ud setInteger:1 forKey:@"integer"];
[ud setBool:YES forKey:@"bool"];
[ud setFloat:1.1 forKey:@"float"];
[ud setValue:@"value" forKey:@"value"];
[ud setDouble:1.1111 forKey:@"double"];
[ud setURL:[NSURL URLWithString:@"http://www.baidu.com"] forKey:@"url"];
}
- NSCoding存储:
// ----------- .h文件------------------
#import <Foundation/Foundation.h>
@interface UserModel : NSObject <NSCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int age;
@end
// ----------- .m文件------------------
#import "UserModel.h"
@implementation UserModel
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeInt:self.age forKey:@"age"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntForKey:@"age"];
}
return self;
}
// ----------- 测试------------------
// NSCoding方式存取值
UserModel *user = [UserModel new];
UserModel *user1 = [UserModel new];
[user setName:@"小明"];
[user setAge:20];
// 数据归档
NSData *archiveCarPriceData = [NSKeyedArchiver archivedDataWithRootObject:user];
[[NSUserDefaults standardUserDefaults] setObject:archiveCarPriceData forKey:@"DataArray"];
// 数据接档
NSData *myEncodedObject = [[NSUserDefaults standardUserDefaults] objectForKey:@"DataArray"];
user1 = [NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];
NSLog(@"name-->%@ age-->%d",user1.name,user1.age);
@end
- Sqlite存储:
作者强推唐巧大神的框架,谁用谁知道,代码就不重复造轮子了自己根据文档很快就能写出来:
https://github.com/burnout-peng/YTKKeyValueStore
总结:
文章对IOS开发中常用到的一些存储技术做了大概介绍,各有利弊没有最好也没有最坏,用到刀刃上都是最好。文章或许存在不足,欢迎你来挑刺,如果感兴趣请添加QQ群:126440594 。