1>沙盒机制
1.2、应用程序不能翻过自己的围墙去访问别的存储空间的内容
1.3、应用程序请求的数据都要通过权限检测,假如不符合条件的话,不会被放行。
Library:存储程序的默认设置或其它状态信息;
1 NSArray *bundlePath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //nssearch是个C语言函数, 找到Document文件夹的路径,返回一个数组, 数组中的只存储了一个元素即文件夹的路径 2 NSString *path = bundlePath.lastObject; // 取出数组中的路径
第二步:在Document文件夹里创建文件
1 path = [path stringByAppendingPathComponent:@"string.txt"]; // 给要创建的文件起个名字
第三步:写入文件
1 NSArray *bundlePath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 2 NSString *path = bundlePath.lastObject; 3 path = [path stringByAppendingString:@"/string.txt”]; 4 //或者: path = [path stringByAppendingPathComponent:@"string.txt"]; 5 6 // 字符串 7 NSString *str = @"这是我写入的字符串"; 8 NSError *error = nil; 9 BOOL judge = [str writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error]; 10 if (judge) { 11 NSLog(@"存储成功"); 12 } else { 13 NSLog(@"error == %@", error); 14 }
其他一些默认支持直接写入文件的类型是:
NSDictionary
NSArray
NSDate等, 更多在这里: NSUserDefaults Class Reference
4>自定义对象要存到文件中的话,需要把自定义对象转换成NSData,让后利用NSUserDefault区保存NSData.
将自定义对象转换成NSData, 首先对象本身需要遵循<NSCoding>协议并实现其中的两个方法:
1 - (void)encodeWithCoder:(NSCoder *)aCoder 2 { // 编码,或者叫序列化,将数据编码成二进制格式 3 [aCoder encodeObject:_imgName forKey:kImageName]; 4 [aCoder encodeObject:_booksName forKey:kBookName]; 5 [aCoder encodeObject:_authorsName forKey:kAuthorName]; 6 }
– initWithCoder:
:解码-
1 - (id)initWithCoder:(NSCoder *)aDecoder 2 { 3 if (self = [super init]) { 4 self.imgName = [aDecoder decodeObjectForKey:kImageName]; 5 self.booksName = [aDecoder decodeObjectForKey:kBookName]; 6 self.authorsName = [aDecoder decodeObjectForKey:kAuthorName]; 7 } 8 return self; 9 }
实现了这两个方法的对象才可以正确转换成NSData并成功写到文件中, 把自定义对象转换成NSData用到的方法是Archive, 书上翻译叫归档 , 对应的解档的方法时Unarchive, 我觉得有点像压缩和解压缩吧.....
- 对应的方法时:
- NSKeyedArchiver class 的 +archiveDataWithRootObject:
-
NSKeyedUnarchiver class 的 + unarchiveObjectWithData:
当使用[NSKeyedArchiver archiveDataWithRootObject:XXX]将自定义对象归档时,会执行到对象中的 encodeWithCoder方法将对象中的数据编码 , 就可以得到NSData对象, 在保存到NSUserDefault里面; 相应的, 当从NSUserDefault中读取出保存的NSData后, 再调用[NSKeyedUnarchiver unarchiveObjectWithData:data]方法解码NSData, 会自动调用到对象内部的 initWithCoder方法, 将NSData解码为对应的对象;
归档写入文件
1 NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 2 path = [path stringByAppendingPathComponent:kFileName]; 3 MyBook *myBook =[[MyBook alloc] init]; 4 NSData *data = [NSKeyedArchiver archivedDataWithRootObject:myBook]; 5 [data writeToFile:path atomically:YES];
读出文件解档
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; path = [path stringByAppendingPathComponent:kFileName]; NSData *data = [NSData dataWithContentsOfFile:path]; MyBook *myBook = [NSKeyedUnarchiver unarchiveObjectWithData:data];
上面的方法不仅对单个对象适用, 对于存储自定义对象的数组,字典也适用, 因为系统的集合类比如NSArray也遵循了<
NSSecureCoding>协议, 感觉应该和<NSCoding>差不多,所以当适用NSKeyedArchiver讲一个保存自定义对象的NSArray数组编码为NSData时, 内部会先调用NSArray的encodeWithCoder, 解码后发现内部都是自定义对象, 然后就分别针对每个自定义对象调用该对象内部的encodeWithCoder方法 , 这样就将一个保存自定义对象的数组转换为了NSData, 相应的解码过程也是差不多, 从NSData解码出NSArray数组时, 先调用NSArray的initWithCoder, 然后针对每个自定义对象调用initWithCoder, 最后解码出一个 自定义对象的数组.
>