最近做项目总是遇到自己觉得很熟悉的东西用的时候却没那么顺手,就考虑把知识点记录下来,一那方便查找,二那也做个知识总结加深记忆。内容也有从网上看到自己用后记下来的,希望这些信息也可以帮到大家。
一、iOS中的沙盒机制
- iOS应用程序只能对自己创建的文件系统读取文件,这个独立、封闭、安全的空间,叫做沙盒。它一般存放着程序包文件(可执行文件)、图片、音频、视频、plist文件、sqlite数据库以及其他文件。
- 每个应用程序都有自己的独立的存储空间(沙盒)
- 一般来说应用程序之间是不可以互相访问
模拟器沙盒的位置
/User/userName/Library/Application Support/iPhone Simulator
当我们创建应用程序时,在每个沙盒中含有三个文件,分别是Document、Library和temp。
- Document:一般用来保存非常重要的数据但不能太大(数据太大同步到云端需要很长时间),因为该目录可以通过itunes同步到icloud上,苹果建议将程序中建立的或在程序中浏览到的文件数据保存在该目录下,iTunes备份和恢复的时候会包括此目录;
- Library:设置程序的默认设置和其他状态信息,NSUserDefaults可以便捷的在Library/Preference进行数据存储和读取。Library/Caches主要用来存放缓存文件,itunes不会备份该目录,该目录在应用退出时也不会被删除;
- temp:创建临时文件的目录,当iOS设备重启时,文件会被自动清除
- 获取沙盒目录
- 获取程序的根目录(home)目录
- 获取程序的根目录(home)目录
- NSString *homePath = NSHomeDirectory()
- 获取Document目录
- 获取Document目录
- NSArray *paths = NSSearchPathDorDirectoriesInDomains(NSDocumentDicrectory,, NSUserDomainMark, YES);
NSString *docPath = [paths lastObject];
- 获取Library目录
NSArray *paths = NSSearchPathForDirectoriseInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *docPath = [paths lastObject];
- 获取Library中的Cache
NSArray *paths = NSSearchPathForDirectoriseInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *docPath = [paths lastObject];
- 获取temp路径
NSString *temp = NSTemporaryDirectory( );
二、那么我们如何来利用沙箱进行文件的存储和读取呢?
首先我们展示如何将一个Person对象保存到一个文件中(这里的扩展名是可以随便写的,这里使用的是archive方式进行的归档持久化,其实质上并不是一个.plist文件,我们知道.plist文件实质上是一个xml文件。而archive方式进行归档后的文件并不是xml格式),代码如下:
- (void)createPerson
{
Person *one = [Person initPersonWithName:"fanly" age:22 heigth:1.7];
//获取Document路径,并在其下创建一个person.plist文件
//注意此行调用到了C的函数,该函数将通过传入的参数值(两个枚举)来返回不同的目录,此处他将放回Document下的所有子目录
//因为我们的例子只有一个目录,所以得到最后一个对象即可
NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask), YES), lastObject];
NSString *path = [documents stringByAppendingPathComponent: @"person.plist"];
[NSKeyedArchiver archiverRootOjbect:person toFile:path];
}
那么是不是所有的对象都可以被存储到文件中呢?cocoa会聪明到知道用户的自定义的类如何转换成文件呢?答案显然是否定的,那么例子里的对象是如何被存储的呢?这是因为我们的Person对象实现了NSCoding协议,我们实现了协议的如下两个方法,这两个方法就告诉了cocoa如何持久化对象到文件中.方法如下:
- (id)initWithCoder:(NSCoder *)decoder
{
self.name = [decoder decodeObjectForKey:@"name"];
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encoderObject:self.name forKey:@"name"];
}
这两个方法只是对Person的那么进行了编码和解码,自然的当我们调用[NSKeyedArchiver archiverRootOjbect:person toFile:path]进行持久化,和调用[NSKeyedUnarchiver unarciverObjectFromFile:path]自然也只能持久化和反持久化我们进行了编码和解码的属性。那些没有进行编码和解码的属性是不会被持久化的。这里需要特别注意的是,如果你的类继承了其他的类,并且这个类也实现了NSCoding协议,那么在子类实现NSCoding协议的相关方法里应该先调用父类的相关方法,这样才会使得持久化和反持久化结果正确。
在cocoa中有些类是可以直接写到.plist文件中的.例如:
- (void)createPlist
{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:@"fanly" forKey:@"name"];
[dict setObject:[NSMumber numberWithInt:12] forKey:@"age"];
[dict setObject:@"ugarden" forKey:@"company"];
[dict writeToFile:[@"person.plist" documentAppend] atomically:YES];
}
最后如何便捷地将数据存储到Library/Preference目录中,示例代码如下:
- (void)savePreference
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"fanly" forKey:@"name"];
[defaults setFloat:186 forKey:@"text_size"];
[defaults setBool:YES forKey:@"auto_login"];
[defaults synchronize];
}
- (void)readPreference
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
BOOL autoLogin = [defaults boolForKey:@"auot_login"];
NSLog(@"autoLogin:%i", autoLogin);
}
每一个应用都有且只有一个NSUserDefaults实例,通过这个对象就可以轻松地将数据存储到应用的Library/Preference目录下,也可以通过这个NSUserDefaults实例提供的方法进行读取
转自:http://blog.csdn.net/wangtie_123/article/details/24330387