iOS开发基础28-数据存储与沙盒机制
在iOS开发中,数据存储是非常重要的一环。本文将详细介绍iOS数据存储的常用方式,并对应用沙盒机制进行深入分析。
一、iOS应用数据存储的常用方式
1. XML属性列表(plist)归档
属性列表(Property List,简称plist)是一种用于存储简单结构化数据的XML格式文件。常用于存储数组、字典等基本数据类型。无法存储自定义对象。
2. Preference(偏好设置)
偏好设置是用于存储应用配置等简单数据的方式,使用NSUserDefaults
类进行操作。它提供了一套标准的解决方案来保存和读取键值对数据,不需要关心具体存储文件的位置。
3. NSKeyedArchiver归档(NSCoding)
NSKeyedArchiver是一种将对象及其属性序列化为二进制数据,并将其写入文件的机制。通过实现NSCoding协议,可以归档和解档自定义对象。
4. SQLite3
SQLite3是一种轻量级关系数据库,适合存储结构化数据。可以通过C函数库进行操作,也可以使用第三方封装库(如FMDB)来简化操作。
5. Core Data
Core Data是iOS提供的对象图管理和持久化框架,适合用于处理更复杂的数据模型和关系。它不仅提供了对SQLite的封装,还支持内存存储、文件存储等多种持久化选项。
二、应用沙盒机制
每个iOS应用都有自己的应用沙盒,与其他应用隔离。这种机制保证了应用的数据安全。
1. 应用沙盒结构
沙盒目录主要包括以下几部分:
- 应用程序包:包含了所有的资源文件和可执行文件。
- Documents:用于存储需要持久化的数据,备份时会包含此目录。适合存储用户生成的文件(如游戏存档)。
- tmp:用于存储临时数据,可能会被系统清理,备份时不包含此目录。
- Library/Caches:用于存储体积大、不需要备份的非重要数据。系统可能会清理此目录。
- Library/Preferences:用于存储应用的所有偏好设置,备份时会包含此目录。
2. 获取应用沙盒目录
// 获取沙盒根路径
NSString *homeDirectory = NSHomeDirectory();
// 获取tmp目录
NSString *tmpPath = NSTemporaryDirectory();
// 获取Documents目录
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
// 获取Library/Caches目录
NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
// 获取Library/Preferences目录
NSString *preferencesPath = [NSSearchPathForDirectoriesInDomains(NSPreferencePanesDirectory, NSUserDomainMask, YES) firstObject];
三、属性列表(plist)存储
1. 存储数组或字典
// 存储数组到plist文件
NSArray *array = @[@"item1", @"item2", @"item3"];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"data.plist"];
[array writeToFile:filePath atomically:YES];
// 读取数组
NSArray *arrayFromFile = [NSArray arrayWithContentsOfFile:filePath];
2. 存储字典到plist文件
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:@"Jane" forKey:@"name"];
[dict setObject:@"123456" forKey:@"phone"];
[dict setObject:@27 forKey:@"age"];
[dict writeToFile:filePath atomically:YES];
// 读取字典
NSDictionary *dictFromFile = [NSDictionary dictionaryWithContentsOfFile:filePath];
四、偏好设置(NSUserDefaults)
1. 保存数据
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"password" forKey:@"pwd"];
[defaults setBool:YES forKey:@"isOn"];
[defaults setInteger:10 forKey:@"num"];
2. 读取数据
NSString *pwd = [[NSUserDefaults standardUserDefaults] objectForKey:@"pwd"];
BOOL isOn = [[NSUserDefaults standardUserDefaults] boolForKey:@"isOn"];
NSInteger num = [[NSUserDefaults standardUserDefaults] integerForKey:@"num"];
五、NSData归档和解档
使用NSData可以将多个对象归档到同一个文件中,也可以实现深复制。
1. 归档多个对象
NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:person1 forKey:@"person1"];
[archiver encodeObject:person2 forKey:@"person2"];
[archiver finishEncoding];
[data writeToFile:filePath atomically:YES];
2. 解档多个对象
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
Person *person1 = [unarchiver decodeObjectForKey:@"person1"];
Person *person2 = [unarchiver decodeObjectForKey:@"person2"];
[unarchiver finishDecoding];
3. 实现自定义对象归档解档
Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject <NSCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int age;
@end
Person.m
@implementation Person
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:self.name forKey:@"name"];
[coder encodeInt:self.age forKey:@"age"];
}
- (instancetype)initWithCoder:(NSCoder *)coder {
if (self = [super init]) {
self.name = [coder decodeObjectForKey:@"name"];
self.age = [coder decodeIntForKey:@"age"];
}
return self;
}
@end
使用示例
Person *p = [[Person alloc] init];
p.name = @"John Doe";
p.age = 30;
// 归档
NSString *tempPath = NSTemporaryDirectory();
NSString *filePath = [tempPath stringByAppendingPathComponent:@"person.data"];
[NSKeyedArchiver archiveRootObject:p toFile:filePath];
// 解档
Person *decodedPerson = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
将来的你会感谢今天如此努力的你!
版权声明:本文为博主原创文章,未经博主允许不得转载。