应用沙盒
目录结构
- Documents
- 保存应用
运行时
生成的需要持久化
的数据 - iTunes同步设备时
会备份
该目录 - 存储的数据
非常重要
,例如:可将游戏存档保存在该目录
- 保存应用
- Library
- Caches
- 保存应用
运行时
生成的需要持久化
的数据 - iTunes同步设备时
不备份
该目录 - 一般存储
体积大
、不需要备份
的数据
- 保存应用
- Preferences
- 保存应用的所有
偏好设置
- iOS的
Settings(设置)
应用会在该目录中查找应用的设置信息 - iTunes同步设备时
会备份
该目录
- 保存应用的所有
- Caches
- tmp
- 保存应用运行时所需的
临时
数据 - 使用完毕后再将相应的文件从该目录删除
- 应用
没有
运行时,系统也可能会清除
该目录下的文件 - iTunes同步设备时
不会备份
该目录
- 保存应用运行时所需的
目录的常见获取方式
- 获取沙盒根目录
// 获取沙盒根目录 NSString *home = NSHomeDirectory();
获取
Documents
路径// 利用NSSearchPathForDirectoriesInDomains函数获取Documents路径 // NSUserDomainMask代表从用户文件夹下找 // YES代表展开路径中的波浪字符“~” NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); // 在iOS中,只有一个目录跟传入的参数匹配,所以这个集合里面只有一个元素 NSString *documents = [array objectAtIndex:0]; // 如果为NO,获取的路径是这样:~/Documents,所以建议使用YES // 如果为YES,获取的路径是这样:/Users/XXX/Library/Developer/CoreSimulator/Devices/CB5D98A8-6756-4E62-9FC6-035CD66A0F71/data/Containers/Data/Application/06C1FF2C-D808-414B-A2B1-351936C54DDD/Documents
- 获取
tmp
路径NSString *tmp = NSTemporaryDirectory();
- 获取
Library/Caches
路径// 类似获取Documents路径,只要将NSUserDomainMask换成NSCachesDirectory NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSCachesDirectory, YES); NSString *documents = [array objectAtIndex:0];
Library/Preference
目录里的数据是通过NSUserDefaults类来操作的
偏好设置
写入偏好设置
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:@"itcast" forKey:@"username"]; [defaults setFloat:18.0f forKey:@"text_size"]; [defaults setBool:YES forKey:@"auto_login"]; // 同步偏好设置,立即写入磁盘 [defaults synchornize];
- 读取偏好设置
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *username = [defaults stringForKey:@"username"]; float textSize = [defaults floatForKey:@"text_size"]; BOOL autoLogin = [defaults boolForKey:@"auto_login"];
plist
- NSString、NSDictionary、NSArray、NSData、NSNumber等类型,就可以使用
writeToFile:atomically:
方法直接
将对象写到属性列表文件中 - 上面这些类型
加载plist
文件是通过方法xxxWithContentsOfFile:
归档
- 如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,
直接
可以用NSKeyedArchiver
进行归档和解档
不是
所有的对象都可以直接用这种方法进行归档,只有遵守了<NSCoding>
协议的对象才可以<NSCoding>
协议有2个方法encodeWithCoder
- 使用
encodeObject:forKey:
方法归档
实例变量
- 使用
initWithCoder
- 使用
decodeObject:forKey
方法解档
实例变量
- 使用
- NSString、NSDictionary、NSArray、NSData、NSNumber等类型的归档和解档
- 归档:
archiveRootObject:toFile:
- 解档:
unarchiveObjectWithFile:
- 归档:
自定义
对象的归档和解档遵守
<NSCoding>
协议,实现协议方法@interface Person : NSObject<NSCoding> @property (nonatomic, copy) NSString *name; @property (nonatomic, assign) int age; @property (nonatomic, assign) float height; @end @implementation Person // 归档 -(void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:self.name forKey:@"name"]; [encoder encodeInt:self.age forKey:@"age"]; [encoder encodeFloat:self.height forKey:@"height"]; } // 解档 -(id)initWithCoder:(NSCoder *)decoder { self.name = [decoder decodeObjectForKey:@"name"]; self.age = [decoder decodeIntForKey:@"age"]; self.height = [decoder decodeFloatForKey:@"height"]; return self; } @end // ***************调用代码*************** // 归档 Person *person = [[[Person alloc] init] autorelease]; person.name = @"MJ"; person.age = 27; person.height = 1.83f; [NSKeyedArchiver archiveRootObject:person toFile:path]; // 解档 Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
NSKeyedArchiver归档对象的
注意事项
- 如果
父类
也遵守了NSCoding协议,应该在encodeWithCoder:
方法中加上一句[super encodeWithCode:encode];
确保继承的实例变量也能被归档 - 如果
父类
也遵守了NSCoding协议,应该在initWithCoder:
方法中加上一句self = [super initWithCoder:decoder];
确保继承的实例变量也能被恢复解档
- 如果
将
多个对象
写入到同一个文件
中,使用NSMutableData归档过程
// 新建一块可变数据区 NSMutableData *data = [NSMutableData data]; // 将数据区连接到一个NSKeyedArchiver对象 NSKeyedArchiver *archiver = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:data] autorelease]; // 开始存档对象,存档的数据都会存储到NSMutableData中 [archiver encodeObject:person1 forKey:@"person1"]; [archiver encodeObject:person2 forKey:@"person2"]; // 存档完毕(一定要调用这个方法) [archiver finishEncoding]; // 将存档的数据写入文件 [data writeToFile:path atomically:YES];
解码过程
// 从文件中读取数据 NSData *data = [NSData dataWithContentsOfFile:path]; // 根据数据,解析成一个NSKeyedUnarchiver对象 NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; Person *person1 = [unarchiver decodeObjectForKey:@"person1"]; Person *person2 = [unarchiver decodeObjectForKey:@"person2"]; // 恢复完毕 [unarchiver finishDecoding];
利用
归档
实现对对象的深度复制
// 临时存储person1的数据 NSData *data = [NSKeyedArchiver archivedDataWithRootObject:person1]; // 解析data,生成一个新的Person对象 Student *person2 = [NSKeyedUnarchiver unarchiveObjectWithData:data]; // 分别打印内存地址 NSLog(@"person1:0x%x", person1); // person1:0x7177a60 NSLog(@"person2:0x%x", person2); // person2:0x7177cf0