iOS数据持久化
来源:互联网 发布:2016cba体测数据 编辑:程序博客网 时间:2024/06/06 15:54
今天想来聊聊iOS的数据持久化。因为今天在家辅导表弟,玩iPad的时候,发现XX应用没有对首页做缓存,正好家里网断了(初三小表弟,你懂得),手机共享伤不起。
回归正题,我建议凡是数据比较多的应用,你都要考虑做下缓存,我看今日头条就不错,在网好的时候,它除了新闻的图片不提前缓存,所有首页文字信息都提前缓存下来了,看的很舒服。
iOS数据持久化,无非几种。
分开讲吧,这篇讲,归档吧。(Archiver持久化)
我推荐一个关于Archive的博文,很详细,这里就不多做说明了。点击打开链接
基本的数据类型如NSString、NSDictionary、NSArray、NSData、NSNumber等可以用属性列表的方法持久化到.plist 文件中,但如果是一些自定义的类的话,属性列表的方法就不管用了。archiver 方法可以做到。
这里强调下,NSKeyedArchive 并不是所有对象都可以通过它来归档的,我们想要归档的话,就必须要遵守NSCoding协议
遵守协议是第一步,之后在遵守协议,希望归档的对象实现两个协议方法,就可以实现数据归档了。
一、 encodeWithCoder:(NSCoder *)encoder 代理方法
-(void)encodeWithCoder:(NSCoder *)encoder{
[super encodeWithCoder:encoder];//不要忘了这个 首先要调用父类的方法,NSObject除外,NSObject 没有实现此方法。
[encoder encodeInt:self.age forKey:@"age"];
[encoder encodeObject:self.name forKey:@"name"];
[encoder encodeFloat:self.height forKey:@"height"];
}
二、initWithCoder:(NSCoder *)decoder 代理方法
-(id)initWithCoder:(NSCoder *)decoder{
self = [super initWithCoder:decoder];//不要忘了这个
self.age = [decoder decodeIntForKey:@"age"];
self.name = [decoder decodeObjectForKey:@"name"];
self.height = [decoder decodeFloatForKey:@"height"];
return self;
}之后的操作就是在归档的地方归档在想解档的地方解档
//创建 -(void)createPerson{ person *p = [[[person alloc] init] autorelease]; p.age = 20; p.name = @"Rio"; p.height =1.75f; //获得Document的路径 NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *path = [documents stringByAppendingPathComponent:@"person.archiver"];//拓展名可以自己随便取 [NSKeyedArchiver archiveRootObject:p toFile:path]; } //读取 -(void)readPerson{ NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *path = [documents stringByAppendingPathComponent:@"person.archiver"]; person *person1 = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; NSLog(@"%@",person1); }
之后,我之前做一款应用时,就用到过这方面来处理缓存
把原理和源码也放在这里了,
原理就是归档,通过请求数据的URL来命名归档的文件名,加上MD5加密一下,基本保证了文件名不重复,
MD5 加密如下,我的处理是给NSString加上了一个类别。
//// ScienceCacheManager.m// 每日新鲜事//// Created by JackYang on 15/9/1.// Copyright (c) 2015年 JackYang. All rights reserved.//#import "NSString+Hashing.h"#import <CommonCrypto/CommonDigest.h>@implementation NSString (NSString_Hashing)- (NSString *)MD5Hash{ const char *cStr = [self UTF8String]; unsigned char result[16]; CC_MD5(cStr, strlen(cStr), result); return [NSString stringWithFormat: @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7], result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]];}@end
剩下的代码就比较通用了。
我都放在这里了。
//// LimitCachManager.h// 每日新鲜事//// Created by JackYang on 15/9/16.// Copyright (c) 2015年 JackYang. All rights reserved.//#import <Foundation/Foundation.h>@interface LimitCachManager : NSObject//保存url 对应的数据+ (void)saveData:(id)object atUrl:(NSString*)url;//读取url对应的数据+ (id)readDataAtUrl:(NSString*)ulr;//判断缓存数据是否有效+ (BOOL)isCacheDataInvalid:(NSString*)url;//计算缓存的大小+ (NSInteger)cacheSize;//清除缓存+ (void)clearDisk;@end
主要实现
#import "LimitCachManager.h"#import "NSString+Hashing.h"@implementation LimitCachManager//得到本地缓存的目录+ (NSString*)cacheDirectory{ //得到沙盒目录下的cache文件夹 NSString *cachDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; cachDir = [cachDir stringByAppendingPathComponent:@"LimitCache"]; //创建LimitCache文件夹,目的是把所有的缓存数据放到该文件夹下面 //attribute:nil只文件夹跟父文件夹一样的读写属性 NSError *error; BOOL bret = [[NSFileManager defaultManager] createDirectoryAtPath:cachDir withIntermediateDirectories:YES attributes:nil error:&error]; if (!bret) { NSLog(@"%@",error); return nil; } return cachDir;}+ (NSString*)cacheFileFullPath:(NSString*)url{ //得到保存的文件的全路径,使用url的MD5加密得到的字符串作为文件名 //这样url和文件名就对应起来了 //[url MD5Hash] 是把url进行MD5加密得到的字符串 //MD5 加密算法是不可逆的 NSString *fileName = [url MD5Hash]; NSString *cacheDir = [self cacheDirectory]; return [cacheDir stringByAppendingPathComponent:fileName];}//保存url 对应的数据//输入的数据,要么是字典,要么数组+ (void)saveData:(id)object atUrl:(NSString*)url{ //首先得到保存的文件路径 NSString *fileFullPath = [self cacheFileFullPath:url]; //写入数据,使用NSKeyedArchiver进行数据转换 NSData *data = [NSKeyedArchiver archivedDataWithRootObject:object]; [data writeToFile:fileFullPath atomically:YES];}//读取url对应的数据+ (id)readDataAtUrl:(NSString*)url{ NSString *fileFullPath = [self cacheFileFullPath:url]; NSData *data = [NSData dataWithContentsOfFile:fileFullPath]; return [NSKeyedUnarchiver unarchiveObjectWithData:data];}//判断缓存数据是否有效+ (BOOL)isCacheDataInvalid:(NSString*)url{ //isDirectory 的参数是返回给我们是否是一个目录 NSString *fileFullPath = [self cacheFileFullPath:url]; BOOL isFileExist = [[NSFileManager defaultManager] fileExistsAtPath:fileFullPath isDirectory:nil]; //获取文件的属性 NSDictionary *attributeDic = [[NSFileManager defaultManager] attributesOfItemAtPath:fileFullPath error:nil]; NSDate *lastModify = attributeDic.fileModificationDate; NSTimeInterval timeInterval = [[NSDate date] timeIntervalSinceDate:lastModify]; BOOL isExpire = (timeInterval > 60*60); if (isFileExist && !isExpire) { return YES; } return NO;}//计算缓存的大小,遍历缓存目录,把文件内容大小累加+ (NSInteger)cacheSize{ NSInteger totalSize = 0; NSString *cacheDir = [self cacheDirectory]; //得到目录的枚举器,使用它来枚举目录下的所有文件 NSDirectoryEnumerator *enmuerator = [[NSFileManager defaultManager]enumeratorAtPath:cacheDir]; for (NSString *fileName in enmuerator) { NSString *fileFullPath = [cacheDir stringByAppendingPathComponent:fileName]; NSDictionary *attributeDic = [[NSFileManager defaultManager] attributesOfItemAtPath:fileFullPath error:nil]; totalSize += attributeDic.fileSize; } return totalSize;}//清除缓存+ (void)clearDisk{ NSString *cacheDir = [self cacheDirectory]; [[NSFileManager defaultManager] removeItemAtPath:cacheDir error:nil];}@end
当使用是就调用,传入url 存储,读取时先判断文件存在不存在,不存在,就获取,存在就读取本地数据。
然后在清除缓存时,将此缓存一并清除。
- IOS 数据持久化
- iOS 数据持久化
- ios数据持久化
- IOS数据持久化
- iOS数据持久化
- ios数据持久化
- iOS数据持久化
- iOS 数据持久化
- iOS 数据持久化
- iOS数据持久化
- iOS数据持久化
- iOS数据持久化
- iOS数据持久化
- iOS 数据持久化
- iOS 数据持久化
- ios数据持久化
- iOS数据持久化
- iOS -- 数据持久化
- C++ STL学习笔记十二 hash_map映照容器
- 韩顺平 java 第38讲 线程
- Java中的String与常量池
- 10.12NOIP模拟赛
- path环境变量
- iOS数据持久化
- 虚拟机下UBUNTU无法NAT上网~~~ 虚拟机是vm7 系统是10 NAT是默认设置~~~~
- 二叉查找树、平衡二叉树、红黑树、B-/B+树性能对比
- 洛谷1262间谍网络(tarjan缩点)
- C#使用线程从一个对话框调用另一个对话框
- 两个项目之间的访问
- 【Foundation-26-1】#import <Foundation/NSDictionary.h>字典,旧
- Java HashMap 的实现原理详解
- 解决qcow2高版本兼容问题