一、沙盒機(jī)制
沙盒是什么
每個(gè)iOS應(yīng)用都有屬于自己的應(yīng)用沙盒(沙盒就是文件系統(tǒng)目錄)夫偶,與其他文件系統(tǒng)隔離,每個(gè)應(yīng)用都只能訪問自己的沙盒觉增。
沙盒的路徑結(jié)構(gòu)
- Document:適合存儲(chǔ)重要的數(shù)據(jù)兵拢, iTunes同步應(yīng)用時(shí)會(huì)同步該文件下的內(nèi)容,(比如游戲中的存檔)
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
- Library/Caches:適合存儲(chǔ)體積大逾礁,不需要備份的非重要數(shù)據(jù)说铃,iTunes不會(huì)同步該文件
NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
- Library/Preferences: 通常保存應(yīng)用的設(shè)置信息, iTunes同步該應(yīng)用時(shí)會(huì)同步此文件夾中的內(nèi)容
- tmp:保存應(yīng)用的臨時(shí)文件,用完就刪除嘹履,系統(tǒng)可能在應(yīng)用沒在運(yùn)行時(shí)刪除該目錄下的文件腻扇,iTunes不會(huì)同步該文件
NSString *path = NSTemporaryDirectory();
獲取沙盒路徑
通過NSSearchPathForDirectoriesInDomains
方法來獲取沙盒路徑
二、數(shù)據(jù)存儲(chǔ)常用方式
偏好設(shè)置(NSUserDefaults)
- 偏好設(shè)置是專門保存應(yīng)用的配置信息的砾嫉,如用戶名幼苛、密碼等,一般不要在偏好設(shè)置中保存其他數(shù)據(jù)焕刮。
- NSUserDefaults保存的數(shù)據(jù)都是不可變的舶沿,取出來的數(shù)據(jù)也是不可變類型墙杯,通過鍵值對方式進(jìn)行存取。
- 如果沒有調(diào)用
synchronize
方法括荡,系統(tǒng)會(huì)根據(jù)I/O情況不定時(shí)刻地保存到文件中高镐。所以如果需要立即寫入文件的就必須調(diào)用synchronize
方法。 - 偏好設(shè)置會(huì)將所有數(shù)據(jù)保存到同一個(gè)文件中畸冲。即preference目錄下的一個(gè)以此應(yīng)用包名來命名的plist文件嫉髓。
實(shí)例如下:
//獲得NSUserDefaults文件
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
//保存內(nèi)容
[userDefaults setValue:@"sunsan" forKey:username];
[userDefaults setValue:@"abcd1234" forKey:userpassword];
//讀取內(nèi)容
NSString * name = [userDefaults valueForKey:username];
NSString * password = [userDefaults valueForKey:userpassword];
plist存儲(chǔ)
plist文件是將某些特定的類,通過XML文件的方式保存在目錄中邑闲。
可以被序列化的類型有以下幾種:
NSArray;
NSMutableArray;
NSDictionary;
NSMutableDictionary;
NSData;
NSMutableData;
NSString;
NSMutableString;
NSNumber;
NSDate;
實(shí)例如下:
//設(shè)置文件名
NSString *fileName = [path stringByAppendingPathComponent:@"students.plist"];
//寫入文件
[array writeToFile:fileName atomically:YES];
//讀取
NSArray *result = [NSArray arrayWithContentsOfFile:fileName];
歸檔解歸檔
通過使用NSKeyArchiver的archiveRootObject: toFile:
方法直接歸檔一個(gè)對象算行,使用NSKeyedUnarchiver的unarchiveObjectWithFile:
解檔對象。
在歸檔自定義對象的時(shí)候监憎,必須遵守NSCoding協(xié)議纱意,并實(shí)現(xiàn)協(xié)議方法:
- 每次歸檔對象時(shí),都會(huì)調(diào)用
encodeWithCoder:
鲸阔,一般在這個(gè)方法里面指定如何歸檔對象中的每個(gè)實(shí)例變量偷霉; - 每次從文件中恢復(fù)對象時(shí),都會(huì)調(diào)用
initWithCoder:
褐筛,一般在這個(gè)方法里面指定如何解碼文件中的數(shù)據(jù)為對象的實(shí)例變量类少。
實(shí)例如下:
//設(shè)置文件名
NSString *fileName = [path stringByAppendingPathComponent:@"person.archiver"];
//進(jìn)行歸檔
[NSKeyedArchiver archiveRootObject:per toFile:fileName];
//進(jìn)行解歸檔
Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:fileName];
以上的存儲(chǔ)方法,都是覆蓋存儲(chǔ)渔扎。如果想要增加一條數(shù)據(jù)就必須把整個(gè)文件讀出來硫狞,然后修改數(shù)據(jù)后再把整個(gè)內(nèi)容覆蓋寫入文件,并不適合大量數(shù)據(jù)的存取晃痴。
SQLite
SQLite簡介
SQLite是一個(gè)輕量級關(guān)系數(shù)據(jù)庫残吩,最初的設(shè)計(jì)目標(biāo)是用于嵌入式系統(tǒng),它占用資源非常少倘核。在iOS中泣侮,只要導(dǎo)入libsqlite3.0.tbd依賴以及引入sqlite3.h頭文件即可。
SQLite是無類型的數(shù)據(jù)庫紧唱,可以保存任何類型的數(shù)據(jù)活尊,對于SQLite來說對字段不指定類型是完全有效的
SQLite近似類似規(guī)則
- 如果類型字符串中包含“int”,那么該字段的親緣關(guān)系是INTEGER
- 如果類型字符串中包含“char”漏益,“clob”或“text”蛹锰,那么該字段的親緣類型是TEXT
- 如果類型字符串中包含“blob”,那么該字段的親緣類型是NONE
- 如果類型字符串中包含“real”绰疤,“floa”或“doub”铜犬,那么該字段的親緣類型是REAL
- 其余情況下,字段的親緣類型為NUMERIC
SQLite字段的約束條件
- not null —— 非空
- unique —— 唯一
- primary key —— 主鍵
- foreign key —— 外鍵
- check —— 條件檢查,確保一列中所有的值滿足一定條件
- default —— 默認(rèn)
- autoincrement —— 自增型變量翎苫,該字段數(shù)據(jù)如果為整形可以自動(dòng)加1
SQLite語句
SQL語言共分為四大類:數(shù)據(jù)查詢語言DQL权埠,數(shù)據(jù)操縱語言DML,數(shù)據(jù)定義語言DDL煎谍,數(shù)據(jù)控制語言DCL攘蔽。
- DML主要包含數(shù)據(jù)的增刪改:
數(shù)據(jù)插入(insert):insert into 表名(字段1,字段2呐粘,……)values(字段1值满俗,字段2值,……)
數(shù)據(jù)更新(update):update 表名 set 字段1=修改值1作岖,字段2=修改值2唆垃,……where 條件
數(shù)據(jù)刪除(delete):delete from 表名 where 條件 - DQL主要用于查詢獲得表中的數(shù)據(jù),其中差用的關(guān)鍵字包含where痘儡,order by辕万,group by和having
數(shù)據(jù)查詢(select):select 查找字段 from 表名 where 條件 - DDL部分包含創(chuàng)建或者刪除表格,定義索引沉删,規(guī)定表之間的鏈接渐尿,以及施加表間的約束
建表命令:create table if not exists 表名(字段1 約束1 約束2……,字段2 約束1 約束2)
刪表命令:drop table if exists 表名
FMDB
FMDB是一款輕量級的框架矾瑰,以O(shè)C的方式對SQLite的C語言API進(jìn)行封裝砖茸,對多線程并發(fā)進(jìn)行處理,所以線程安全殴穴。
FMDB常用類
FMDatabase:一個(gè)FMDatabase對象就代表一個(gè)單獨(dú)的SQLite數(shù)據(jù)庫凉夯,用來執(zhí)行SQL語句
FMResultSet:使用FMDatabase執(zhí)行查詢后的結(jié)果集
FMDatabaseQueue:用于在多線程中執(zhí)行多個(gè)查詢或更新,它是線程安全的
FMDB操作
- 使用FMDataBase類建立數(shù)據(jù)庫
//獲取Documents路徑
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject ;
//生成數(shù)據(jù)庫路徑
NSString *filePath = [path stringByAppendingPathComponent:@"person.sqlite"];
//獲取數(shù)據(jù)庫
database = [FMDatabase databaseWithPath:filePath];
if ([database open]) {
NSLog(@"數(shù)據(jù)庫打開成功");
}else{
NSLog(@"打開數(shù)據(jù)庫失敗");
}
- 表的創(chuàng)建
BOOL result = [database executeUpdate:@"create table if not exists person (name text primary key not null, city text, age integer)"];
if (result) {
NSLog(@"創(chuàng)建表成功");
} else {
NSLog(@"創(chuàng)建表失敗");
}
- 添加數(shù)據(jù)
BOOL result = [database executeUpdate:@"insert into person (name,city,age) values (?,?,?)",per.name,per.city,@(per.age)];
if (result) {
NSLog(@"添加數(shù)據(jù)成功");
} else {
NSLog(@"添加數(shù)據(jù)失敗");
}
- 刪除數(shù)據(jù)
BOOL result = [database executeUpdate:@"delete from person where name = ?",per.name];
if (result) {
NSLog(@"刪除數(shù)據(jù)成功");
} else {
NSLog(@"刪除數(shù)據(jù)失敗");
}
- 修改數(shù)據(jù)
BOOL result = [database executeUpdate:@"update person set city = ?,age = ? where name = ?",per.city,@(per.age),per.name];
if (result) {
NSLog(@"修改數(shù)據(jù)成功");
} else {
NSLog(@"修改數(shù)據(jù)失敗");
}
- 查詢所有數(shù)據(jù)
FMResultSet *result = [database executeQuery:@"select * from person"];
while ([result next]) {
Person *per = [[Person alloc] init];
per.name = [result stringForColumn:@"name"];
per.city = [result stringForColumn:@"city"];
per.age = [result intForColumn:@"age"];
[array addObject:per];
}
- 關(guān)閉數(shù)據(jù)庫
if ([database close]) {
NSLog(@"關(guān)閉數(shù)據(jù)庫成功");
} else {
NSLog(@"關(guān)閉數(shù)據(jù)庫失敗");
}