iOS NSKeyedArchiver(轻量级缓存)

iOS本地缓存数据方式有五种:

1.直接写文件方式:可以存储的对象有NSString、NSArray、NSDictionary、NSData、NSNumber,数据全部存放在一个属性列表文件(*.plist文件)中。

2.NSUserDefaults(偏好设置),用来存储应用设置信息,文件放在perference目录下。

3.归档操作(NSkeyedArchiver),不同于前面两种,它可以把自定义对象存放在文件中。

4.coreData:coreData是苹果官方iOS5之后推出的综合型数据库,其使用了ORM(Object Relational Mapping)对象关系映射技术,将对象转换成数据,存储在本地数据库中。coreData为了提高效率,甚至将数据存储在不同的数据库中,且在使用的时候将本地数据放到内存中使得访问速度更快。我们可以选择coreData的数据存储方式,包括sqlite、xml等格式。但也正是coreData 是完全面向对象的,其在执行效率上比不上原生的数据库。除此之外,coreData拥有数据验证、undo等其他功能,在功能上是几种持久化方案最多的。

5.FMDB:FMDB是iOS平台的SQLite数据库框架,FMDB以OC的方式封装了SQLite的C语言API,使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码,对比苹果自带的Core Data框架,更加轻量级和灵活,提供了多线程安全的数据库操作方法,有效地防止数据混乱。

接下来我将介绍第三种缓存机制 归档操作:

作为轻量级存储的持久化方案,数据归档是进行加密处理的,数据在经过归档处理会转换成二进制数据,所以安全性要远远高于属性列表。另外使用归档方式,我们可以将复杂的对象写入文件中,并且不管添加多少对象,将对象写入磁盘的方式都是一样的。

使用NSKeyedArchiver对自定义的数据进行序列化,并且保存在沙盒目录下。使用这种归档的前提是让存储的数据模型遵守NSCoding协议并且实现其两个协议方法。(当然,如果为了更加安全的存储,也可以遵守NSSecureCoding协议,这是iOS6之后新增的特性)

使用归档操作存储数据的主要好处是,不同于前面两种方法只能存储几个常用的数据类型的数据,NSKeyedArchiver可以存储自定义的对象。

/**代码示例**/

先创建一个继承NSObject的类,该类遵守NSCoding协议

#import <Foundation/Foundation.h>

@interface JXItem : NSObject<NSCoding>

@property (nonatomic, assign) NSInteger collect;

@property (nonatomic, assign) NSInteger collect_num;

@property (nonatomic, assign) NSInteger courseid;

@property (nonatomic, copy)   NSString *coverpic;

@property (nonatomic, assign) long long date_end;

@property (nonatomic, assign) long long date_start;

@property (nonatomic, assign) NSInteger groupid;

@property (nonatomic, assign) NSInteger invitation_code;

@property (nonatomic, assign) NSInteger is_live;

@property (nonatomic, assign) NSInteger paid;

@property (nonatomic, assign) NSInteger play_num;

@property (nonatomic, copy)   NSString *price;

@property (nonatomic, assign) NSInteger product_id;

@property (nonatomic, copy  ) NSString *product_info;

@property (nonatomic, copy)   NSString *productname;

@property (nonatomic, copy)   NSString *realname;

@property (nonatomic,assign)  NSInteger recomment;

@property (nonatomic ,copy)   NSString *stream_url;

@property (nonatomic, copy)   NSString *time_duan;

@property (nonatomic,assign)  NSInteger  user_id;

@property (nonatomic, assign) NSInteger viewtype;

@property (nonatomic, assign) NSInteger live_in;

+ (instancetype)randomDictionary:(NSDictionary *)dictionary;

@end

其次在模型的.m文件进行读取解析,归档和解归档

#import "JXItem.h"

@implementation JXItem

+ (instancetype)randomDictionary:(NSDictionary *)dictionary {

JXItem *item = [[JXItem alloc] init];

[item setValuesForKeysWithDictionary:dictionary];

return item;

}

- (void)encodeWithCoder:(NSCoder *)aCoder {

[aCoder encodeInteger:self.collect forKey:@"collect"];

[aCoder encodeInteger:self.collect_num forKey:@"collect_num"];

[aCoder encodeInteger:self.courseid forKey:@"courseid"];

[aCoder encodeObject:self.coverpic forKey:@"coverpic"];

[aCoder encodeInteger:self.date_end forKey:@"date_end"];

[aCoder encodeInteger:self.date_start forKey:@"date_start"];

[aCoder encodeInteger:self.groupid forKey:@"groupid"];

[aCoder encodeInteger:self.invitation_code forKey:@"invitation_code"];

[aCoder encodeInteger:self.paid forKey:@"paid"];

[aCoder encodeInteger:self.play_num forKey:@"play_num"];

[aCoder encodeObject:self.price forKey:@"price"];

[aCoder encodeInteger:self.product_id forKey:@"product_id"];

[aCoder encodeObject:self.product_info forKey:@"product_info"];

[aCoder encodeObject:self.productname forKey:@"productname"];

[aCoder encodeObject:self.realname forKey:@"realname"];

[aCoder encodeInteger:self.recomment forKey:@"recomment"];

[aCoder encodeObject:self.stream_url forKey:@"stream_url"];

[aCoder encodeObject:self.time_duan forKey:@"time_duan"];

[aCoder encodeInteger:self.user_id forKey:@"user_id"];

[aCoder encodeInteger:self.viewtype forKey:@"viewtype"];

[aCoder encodeInteger:self.live_in forKey:@"live_in"];

}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {

self = [super init];

if (self) {

_collect = [aDecoder decodeIntegerForKey:@"collect"];

_collect_num = [aDecoder decodeIntegerForKey:@"collect_num"];

_coverpic = [aDecoder decodeObjectForKey:@"coverpic"];

_date_end = [aDecoder decodeIntegerForKey:@"date_end"];

_date_start = [aDecoder decodeIntegerForKey:@"date_start"];

_groupid = [aDecoder decodeIntegerForKey:@"groupid"];

_invitation_code = [aDecoder decodeIntegerForKey:@"invitation_code"];

_paid = [aDecoder decodeIntegerForKey:@"paid"];

_price = [aDecoder decodeObjectForKey:@"price"];

_product_id = [aDecoder decodeIntegerForKey:@"product_id"];

_product_info = [aDecoder decodeObjectForKey:@"product_info"];

_productname = [aDecoder decodeObjectForKey:@"productname"];

_realname = [aDecoder decodeObjectForKey:@"realname"];

_recomment = [aDecoder decodeIntegerForKey:@"recomment"];

_stream_url = [aDecoder decodeObjectForKey:@"stream_url"];

_time_duan = [aDecoder decodeObjectForKey:@"time_duan"];

_viewtype = [aDecoder decodeIntegerForKey:@"viewtype"];

}

return self;

}

@end

另外建立一个数据的管理类JXItemStore

#import <Foundation/Foundation.h>

@class JXItem;

@interface JXItemStore : NSObject

@property (nonatomic, copy) NSString *archiveName;

@property (nonatomic, strong) NSArray *allItem;

+ (instancetype)sharedStore;

- (JXItem *)createItem:(JXItem *)item;

/**

*  删除对象

*

*  @param item 需要删除的对象

*/

- (void)removeItem:(JXItem *)item;

/**

*  移除对象

*

*  @param fromIndex 移除对象的起始位置

*  @param toIndex 移除后的位置

*/

- (void)moveItemAtIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex;

- (BOOL)saveChanages;

@end

//

#import "JXItemStore.h"

#import "JXItem.h"

@interface JXItemStore()

@property (nonatomic, strong) NSMutableArray *privateItems;

@end

@implementation JXItemStore

+ (instancetype)sharedStore {

static JXItemStore *sharedStore = nil;

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

sharedStore = [[self alloc] init];

});

return sharedStore;

}

- (BOOL)saveChanages {

return [NSKeyedArchiver archiveRootObject:self.privateItems

toFile:[self itemArchivePath]];

}

- (NSArray *)getAll {

[self.privateItems setArray:[NSKeyedUnarchiver unarchiveObjectWithFile: [self itemArchivePath]]];

return self.privateItems;

}

- (void)removeItem:(JXItem *)item {

[self.privateItems removeObjectIdenticalTo:item];

//

}

- (void)moveItemAtIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex {

if (fromIndex == toIndex) {

return;

}

JXItem *item = self.privateItems[fromIndex];

[self.privateItems removeObjectAtIndex:fromIndex];

[self.privateItems insertObject:item atIndex:toIndex];

}

- (NSMutableArray *)privateItems {

if (!_privateItems) {

_privateItems = [[NSMutableArray alloc] init];

[self getAll];

}

return _privateItems;

}

- (NSArray *)allItem {

return [self.privateItems copy];

}

- (JXItem *)createItem:(JXItem *)item {

[self.privateItems addObject:item];

return item;

}

- (NSString *)itemArchivePath {

NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentDirectory = [documentDirectories firstObject];

if (!_archiveName) {

return  [documentDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"putcharTems.archive"]];

}

return [documentDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@items.archive",_archiveName]];

}

这样子,我们就可以进行数据的请求了 ZXHttpRequestManager类只是一个对AFNetworking请求库封装的一个网络请求管理类

#define kDomain_name @"www.niulaile.tv"//test.91kanjian.com"

#import "ViewController.h"

#import "ZXHttpRequestManager.h"

#import "JXItemStore.h"

#import "JXItem.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

NSString *url = [NSString stringWithFormat:@"http://%@//kj.php?m=Course&a=dotv_newindex",kDomain_name];

JXItemStore *manager = [JXItemStore sharedStore];

manager.archiveName = @"JXModel";

__weak typeof(manager) weakManager = manager;

[[ZXHttpRequestManager manager] POST:url parameters:nil success:^(ZXHttpRequestCode code, id response) {

if(code == ZXHttpRequestSuccess) {

if([response[@"status"] integerValue] == 1) {

for (NSDictionary *dict in response[@"data"]) {

JXItem *item = [JXItem randomDictionary:dict];

[weakManager createItem:item];

}

NSArray *array = weakManager.allItem;

NSLog(@"%@",array);

}

}

} failure:^(NSInteger errorCode, NSError *error) {

NSArray *array = weakManager.allItem;

NSLog(@"%@",array);

}];

}

- (void)didReceiveMemoryWarning {

[super didReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

@end

时间: 2024-10-05 21:33:34

iOS NSKeyedArchiver(轻量级缓存)的相关文章

麦子学院ios笔记:IOS把图片缓存到本地的几种方法

把ios的图片缓存到本地的方法有几种?现在来看看学生在麦子学院学习ios开发的笔记中有讲到哪几种方法呢? <code>把图片缓存到本地,在很多场景都会用到,如果是只储存文字信息,那建一个plist文件,或者数据库就能很方便的解决问题,但是如果存图片到沙盒就没那么方便了.这里介绍两种保存图片到沙盒的方法. </code> 一.把图片转为base64的字符串存到数据库中或者plist文件中,然后用到的时候再取出来 <code class="hljs" obje

玩转iOS开发 - 数据缓存

Why Cache 有时候.对同一个URL请求多次,返回的数据可能都是一样的,比方server上的某张图片.不管下载多少次,返回的数据都是一样的. 上面的情况会造成下面问题 (1)用户流量的浪费 (2)程序响应速度不够快 解决上面的问题.一般考虑对数据进行缓存. 数据缓存 为了提高程序的响应速度,能够考虑使用缓存(内存缓存\硬盘缓存)r 第一次请求数据时,内存缓存中没有数据.硬盘缓存中没有数据. 缓存数据的过程: ? 当server返回数据时,须要做下面步骤 (1)使用server的数据(比方解

iOS开发网络缓存原理

一.关于同一个URL的多次请求 有时候,对同一个URL请求多次,返回的数据可能都是一样的,比如服务器上的某张图片,无论下载多少次,返回的数据都是一样的. 上面的情况会造成以下问题 (1)用户流量的浪费 (2)程序响应速度不够快 解决上面的问题,一般考虑对数据进行缓存. 二.缓存 为了提高程序的响应速度,可以考虑使用缓存(内存缓存\硬盘缓存) 第一次请求数据时,内存缓存中没有数据,硬盘缓存中没有数据. 缓存数据的过程 当服务器返回数据时,需要做以下步骤 (1)使用服务器的数据(比如解析.显示) (

iOS 清理文件缓存

本文摘自:<msp的昌伟哥哥-iOS开发-清理缓存功能的实现>摘下来的目的就是为了能够学习.还望看到文章的同学,前往原创的博客园.感谢msp的昌伟哥哥的分享精神. 移动应用在处理网络资源时,一般都会做离线缓存处理,其中以图片缓存最为典型,其中很流行的离线缓存框架为SDWebImage. 但是,离线缓存会占用手机存储空间,所以缓存清理功能基本成为资讯.购物.阅读类app的标配功能. 今天介绍的离线缓存功能的实现,主要分为缓存文件大小的获取.删除缓存文件的实现. 获取缓存文件的大小 由于缓存文件存

iOS开发—清除缓存

iOS开发—清除缓存 一.修改了系统的头文件 报错示例: fatal error: file '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSArray.h' has been modified si

iOS数据库离线缓存思路和网络层封装

一直想总结一下关于iOS的离线数据缓存的方面的问题,然后最近也简单的对AFN进行了再次封装,所有想把这两个结合起来写一下.数据展示型的页面做离线缓存可以有更好的用户体验,用户在离线环境下仍然可以获取一些数据,这里的数据缓存首选肯定是SQLite,轻量级,对数据的存储读取相对于其他几种方式有优势,这里对AFN的封装没有涉及太多业务逻辑层面的需求,主要还是对一些方法再次封装方便使用,解除项目对第三方的耦合性,能够简单的快速的更换底层使用的网络请求代码.这篇主要写离线缓存思路,对AFN的封装只做简单的

iOS开发 数据缓存-数据库

iOS中数据存储方式 Plist(NSArray\NSDictionary) Preference(偏好设置\NSUserDefaults) NSCoding (NSKeyedArchiver\NSkeyedUnarchiver) SQlite3 Core Date Plist.Preference.NSCoding的存储方式 详见 iOS开发 文件存储方式 数据库的存储方式 Core Date:Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将O

android轻量级缓存框架ASimpleCache分析

框架地址 https://github.com/yangfuhai/ASimpleCache  此框架作者为大名鼎鼎的afinal作者 官方简介: ASimpleCache 是一个为android制定的 轻量级的 开源缓存框架.轻量到只有一个java文件(由十几个类精简而来). (有个问题是作者所说的自动失效,其实是在获取数据时判断存入缓存的数据是否过期,如果过期,则删除数据缓存,返回null.当然,如果真正的自动删除,应该只能开启服务,不断判断是否过期来删除吧,也没有必要) ---------

 iOS 网络请求缓存:NSURLCache详解

我读过一些开源项目的网络请求缓存的代码,基本上都是采用在本地存文件的方式进行缓存.如果你打算在你的项目中加入网络请求的缓存,可能你并不需要自己造一个轮子,了解一下 NSURLCache 就足够.本文为大家接收的就是ios开发中的NSURLCache相关使用,一起来看看吧. 缓存 首先, NSURLCache 提供的是内存以及磁盘的综合缓存机制.许多文章谈到,使用NSURLCache 之前需要在 AppDelegate 中缓存空间的设置: - (BOOL)application:(UIApplic