在iOS系统的安全机制,每个APP都有自己的文件目录,且只能访问自己的文件目录。该机制被称为沙盒机制。
沙盒文件结构如下:

Documents
保存用户创建的文档文件的目录,用户可以通过文件分享分享该目录下的文件。在iTunes和iCloud备份时会备份该目录。建议保存你希望用户看得见的文件。
Library
苹果不建议在该目录下保存任何用户相关数据,而是保存APP运行需要的修改数据,当然用户可以根据自己的实际需要进行保存。
Cache
建议保存数据缓存使用。在用户的磁盘空间已经使用完毕时有可能删除该目录下的文件,在APP使用期间不会删除,APP没有运行时系统有可能进行删除。需要持久化的数据建议不要保存在该目录下,以免系统强制删除。
Preferences
用户偏好存储目录,在使用NSUserDefaults或者CFPreferences接口保存的数据保存在该目录下,编程人员不需要对该目录进行管理。在iTunes和iCloud备份时会备份该目录。
tmp
苹果建议该目录用来保存临时使用的数据,编程人员应该在数据长时间内不使用时主动删除该目录下的文件,在APP没有运行期间,系统可能删除该目录下的文件。在iTunes和iCloud备份时不会备份该目录。
//沙盒根目录
NSString *homePath = NSHomeDirectory();
//document目录
NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
//library目录
NSString *libraryPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES).firstObject;
//caches目录
NSString *cachesPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
//application support目录
NSString *applicationSupportPath = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES).firstObject;
//preference目录
NSString *preferencePath = NSSearchPathForDirectoriesInDomains(NSPreferencePanesDirectory, NSUserDomainMask, YES).firstObject;
//tem目录
NSString *temPath = NSTemporaryDirectory();
如果对是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,就可以使用writeToFile:atomically:方法直接将对象写到属性列表文件中, plist是一种XML格式的文件
归档NSDictionary: 将一个NSDictionary对象归档到一个plist属性列表中
// 将数据封装成字典
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:@"张三" forKey:@"name"];
[dict setObject:@"155xxxxxxx" forKey:@"phone"];
[dict setObject:@"27" forKey:@"age"];
// 将字典持久化到Documents/stu.plist文件中
[dict writeToFile:path atomically:YES];
恢复NSDictionary: 读取plist,恢复NSDictionary对象
// 读取Documents/stu.plist的内容,实例化
NSDictionaryNSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSLog(@"name:%@", [dict objectForKey:@"name"]);
NSLog(@"phone:%@", [dict objectForKey:@"phone"]);
NSLog(@"age:%@", [dict objectForKey:@"age"]);
iOS提供了一套标准的解决方案来为应用加入偏好设置功能。 每个应用都有个NSUserDefaults实例,通过它来存取偏好设置。
比如,保存用户名等:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"张三" forKey:@"username"];
[defaults setFloat:18.0f forKey:@"userAge"];
读取保存的设置:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *username = [defaults stringForKey:@"username"];
float userAge = [defaults floatForKey:@"userAge"];
注意: UserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘应用程序就终止了。出现以上问题,可以通过调用synchornize方法[defaults synchornize]; 强制写入
如果对象是 NSString、NSDictionary、NSArray、NSData、NSNumber等类型,可以直接用NSKeyedArchiver进行归档和恢复
不是所有的对象都可以直接用这种方法进行归档,只有遵守了NSCoding协议的对象才可以。
NSCoding 协议有2个方法:
归档数组等Cocoa Object
NSArray *array = [NSArray arrayWithObjects:@”a”,@”b”,nil];
[NSKeyedArchiver archiveRootObject:array toFile:path];
归档自定义对象:UserModel 实现 NSCoding:
@interface UserModel : NSObject <NSCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
@implementation UserModel
#pragma mark - NSCoding
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[super encodeWithCode: aCoder];
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeInteger:self.age forKey:@"age"];
}
@end
归档方法
[NSKeyedArchiver archiveRootObject:person toFile:path];
解档方法
UserModel *userModel = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
SQLite 是一款嵌入式的轻量关系型文件数据库。 它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。 它的处理速度比 Mysql、PostgreSQL 这两款著名的数据库都还快。
数据库存储数据的步骤
推荐使用FMDB, FMDB以OC的方式封装了SQLite的C语言API
常用的SQL语句
create table t_student (id integer, name text, age inetger, score real);
create table if not exists Student (
ID integer primary key autoincrement,
Name varchar(128),
Age integer,
Class interger default 0,
RegisterTime datetime,
Money float default 0,
Birthday date
);
/// 删表: drop table 表名; drop table if exists 表名;
drop table t_student;
/// 插入数据: insert into 表名 (字段1, 字段2, …) values (字段1的值, 字段2的值, …);
insert into t_student (name, age) values (‘张三’, 10);
/// update 表名 set 字段1 = 字段1的值, 字段2 = 字段2的值, … ;
update t_student set name = ‘jack’, age = 20;
///delete from 表名;
// 删除指定ID值为2的记录
delete from t_student where ID=2;
// 删除t_student表中所有的记录(慎重)
delete from t_student;
/// select 字段1, 字段2, … from 表名; select * from 表名;
select name, age from t_student ;
select * from t_student ;
// 条件查询
select * from t_student where age > 10 ;
// 模糊查询
select * from t_student where name like '%张%' or phone like '%张%';
Realm 移动数据库是一种新型的移动数据库,它是全新的, Realm 移动数据库因此 和 SQLite 没有任何关系 也不是另外一个 SQL 数据库;它的目标就是去解决这些领域里面的已知问题。但是 Realm 移动数据库也 不是一个键-值存储 类型,这种存储类型在某些情况下非常棒,但是开发者真的很想直接和本地对象打交道。
Realm 移动数据库 也不是一个 ORM。ORM 把 SQL 数据库的表结构中平的数据转换成了对象图,这样它们能被本地代码使用了。 Realm 的客制化存储引擎不需要把数据转换成对象图,所以它不需要 ORM
Realm 数据库 直接存储对象 在磁盘上,当然需要最少的类型和结构的转换。英文它没有映射关系或者其它动态解读实体,Realm 移动数据库能够从内存到磁盘非常迅速地操作对象。