iOS应用沙盒机制
iOS应用程序只能在为该程序创建的文件系统中读取文件,不可以去其他地方访问,此区域被称为沙盒,所以所有的非代码文件都要保存在此,例如图像、图标、声音、属性列表、文本文件等。
应用沙盒机制下,每个应用程序都有自己的存储空间;应用程序不能翻过自己的围墙去访问别的存储空间的内容;应用程序请求的数据都要通过权限检测,假如不符合条件的话,不会被放行。
XCode中的应用沙盒目录:
1、模拟器的位置:
/Users/username/Library/Developer/CoreSimulator/Devices/EBABD400-5D00-49F8-AB77-73ACB15B83CD
devices目录下存放着XCode中包含的模拟器,在device.plist中可以看到该模拟器的基本信息。
![Upload Snip20160723_39.png failed. Please try again.]
2、每个应用的沙盒目录:
/Users/username/Library/Developer/CoreSimulator/Devices/EBABD400-5D00-49F8-AB77-73ACB15B83CD/data/Containers/Data/Application/
![Upload Snip20160723_42.png failed. Please try again.]
NSString *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];]
应用沙盒的结构:
1、Documents :保存应用运行时生成的需要持久化的数据,iTunes同步设备时 会备份该目录 。例如,游戏应用可将游戏存档保存在该目录
2、tmp :保存应用运行时所需的 临时数据 ,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份该目录
3、Library/Caches :保存应用运行时生成的需要持久化的数据,iTunes同步设备时 不会备份该目录 。一般存储体积大、不需要备份的非重要数据
4、Library/Preference :保存应用的所有偏好设置,iOS的Settings(设置)应用会在该目录中查找应用的设置信息。iTunes同步设备时 会备份该目录
获取当前应用沙盒的目录:
NSString *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
=================我是分隔线=================
切正题吧,以下介绍几个轻量级的数据存储方式。
一、plist(property list)
它是一种用来存储串行化后的对象的文件,是xml格式的。
使用场景:plist文件通常用于存储用户设置,也可以用于存储捆绑的信息。
支持的数据类型:可以被序列化的对象类型:
NSArray/NSMutableArray;
NSDictionary/NSMutableDictionary;
NSData/NSMutableData;
NSString/NSMutableString;
NSNumber;
存取:
使用writeToFile:automically:
方法直接将对象写到plist文件中。
可以使用NSArray或者NSDictionary来取plist里面的数据:
[NSArray arrayWithContentsOfFile:filePath];
二、Preference
存储目录在library/Preferences,是一个plist文件。适合存储轻量级的本地数据。
支持的数据格式有:
NSNumber(Integer、Float、Double),NSString,NSDate,NSArray,NSDictionary,BOOL类型
存:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"itcast" forKey:@"username"];
[defaults setFloat:18.0f forKey:@"text_size"];
[defaults setBool:YES forKey:@"auto_login"];
UserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘应用程序就终止了。可以通过调用synchornize方法强制写入
[defaults synchornize];
取:
NSString *username = [defaults stringForKey:@"username"];
float textSize = [defaults floatForKey:@"text_size"];
BOOL autoLogin = [defaults boolForKey:@"auto_login"];
三、NSKeyedArchiver
归档(又名序列化),把对象转为字节码,以文件的形式存储到磁盘上;程序运行过程中或者当再次重写打开程序的时候,可以通过解归档(反序列化)还原这些对象。
plist只能存储Foundation框架中的对象,归档除了可以归档Foundation框架中的对象以外,还可以归档实现了NSCoding协议的自定义对象。
归档和解归档其中任意对象都需要归档和解归档整个文件。
归档后的文件是加密的,所以归档文件的扩展名可以随意取。
归档方式分三种
1、对Foundation框架中对象进行归档。
一次只能归档一个对象,如果是多个对象归档需要分开进行。
// 归档:
NSArray *archiveAry = @[@"jereh",@"ios"];
[NSKeyedArchiver archiveRootObject: archiveAry toFile:filePath];
// 解归档:
[NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
2、对自定义的内容进行归档。
在带键的归档中,每个归档字段都有一个key值,解归档时key值要与归档时key值匹配。
带键归档可以一次存储多个对象。
//归档:
//1. 使用NSData存放归档数据
NSMutableData *archiverData = [NSMutableData data];
//2. 创建归档对象
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:archiverData];
//3. 添加归档内容 (设置键值对)
[archiver encodeObject:@"jereh" forKey:@"name"]; [archiver encodeInt:20 forKey:@"age"]; [archiver encodeObject:@[@"ios",@"oc"] forKey:@"language"];
//4. 完成归档
[archiver finishEncoding];
//5. 将归档的信息存储到磁盘上
if ([archiverData writeToFile:filePath atomically:YES]) {
NSLog(@"archiver success");
}
//解归档:
//1. 从磁盘读取文件,生成NSData实例
NSData *unarchiverData = [NSData dataWithContentsOfFile:filePath];
//2. 根据Data实例创建和初始化解归档对象
NSKeyedUnarchiver *unachiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:unarchiverData];
//3. 解归档,根据key值访问
NSString *name = [unachiver decodeObjectForKey:@"name"];
int age = [unachiver decodeIntForKey:@"age"];
NSArray *ary = [unachiver decodeObjectForKey:@"language"];
3、对自定义的对象进行归档
自定义的对象归档需要实现NSCoding协议,并且实现协议中的方法。
NSCoding协议中有两个方法:encodeWithCoder方法对对象属性进行编码,在对象归档时调用;initWithCoder方法解码归档数据来初始化对象,在对象解归档时调用。
@interface Student : NSObject <NSCoding>
@property (nonatomic, assign) int idNum;
@property (nonatomic, copy) NSString *name;
@end
@implementation Student
// 编码 对对象属性进行编码的处理
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeInt:_idNum forKey:@“id"];
[aCoder encodeObject:_name forKey:@“name"];
}
// 解码 解码归档数据来初始化对象
- (id)initWithCoder:(NSCoder *
)aDecoder{
if (self = [super init]) {
_idNum = [aDecoder decodeIntForKey:@“id"];
_name = [aDecoder decodeObjectForKey:@“name"];
} return self;
}
@end
网友评论