- 數(shù)據(jù)的存儲(chǔ),一般都是存儲(chǔ)在本地的沙盒中
沙盒介紹
- 沙盒,也就是應(yīng)用程序運(yùn)行后,在本地設(shè)備上生成的程序文件系統(tǒng)目錄,主要包括以下四個(gè)文件夾
- Documents:保存應(yīng)用運(yùn)行時(shí)生成的需要持久化的數(shù)據(jù),iTunes同步設(shè)備時(shí)會(huì)備份該目錄,例如,游戲應(yīng)用可將游戲存檔保存在該目錄
- tmp:保存應(yīng)用運(yùn)行時(shí)所需的臨時(shí)數(shù)據(jù),使用完畢后再將相應(yīng)的文件從該目錄刪除,應(yīng)用沒有運(yùn)行時(shí),系統(tǒng)也可能會(huì)清除該目錄下的文件,iTunes同步設(shè)備時(shí)不會(huì)備份該目錄
- Library/Caches:保存應(yīng)用運(yùn)行時(shí)生成的需要持久化的數(shù)據(jù),iTunes同步設(shè)備時(shí)不會(huì)備份該目錄,一般存儲(chǔ)體積大/不需要備份的非重要數(shù)據(jù)
- Library/Preference:保存應(yīng)用的所有偏好設(shè)置,iOS的Settings(設(shè)置)應(yīng)用會(huì)在該目錄中查找應(yīng)用的設(shè)置信息,iTunes同步設(shè)備時(shí)會(huì)備份該目錄
沙盒目錄的獲取方式
- 1.獲取到沙盒的最外層的文件目錄的方式
NSHomeDirectory()
返回的路徑是 :/Users/mario/Library/Developer/CoreSimulator/Devices/5A68CA7E-130D-47AD-906E-9D1AC482D9D1/data/Containers/Data/Application/185D8F8D-7882-4BB5-8754-5EB74F6AE901
對(duì)應(yīng)的目錄文件如下圖
Snip20160814_1.png - 2.獲取temp文件夾的路徑
NSTemporaryDirectory();
返回的路徑是 : /Users/mario/Library/Developer/CoreSimulator/Devices/5A68CA7E-130D-47AD-906E-9D1AC482D9D1/data/Containers/Data/Application/7D48C9F2-C013-48A8-98D7-DF33FA4EC879/tmp/
對(duì)應(yīng)的文件夾目錄如下圖
Snip20160814_3.png - 3.指定想要獲取的文件夾的路徑
/*參數(shù)解讀:
directory:獲取哪個(gè)文件夾
domainMask:在哪個(gè)路徑下搜索
expandTilde:是否展開路徑.
這個(gè)方法獲取出的結(jié)果是一個(gè)數(shù)組.因?yàn)橛锌梢运阉鞯蕉鄠€(gè)路徑.
*/
NSSearchPathForDirectoriesInDomains(<#NSSearchPathDirectory directory#>, <#NSSearchPathDomainMask domainMask#>, <#BOOL expandTilde#>)
數(shù)據(jù)本地化存儲(chǔ)的方式
1.plist文件
這種方式存儲(chǔ)數(shù)據(jù),只能以系統(tǒng)能識(shí)別的數(shù)據(jù)模型或?qū)ο筮M(jìn)行存儲(chǔ),不能是自定義的模型或?qū)ο?/p>
- 存儲(chǔ)(以字典或數(shù)組的形式存儲(chǔ))
示例:
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSArray *array = @[@"xmg",@10];
//拼接文件名
NSString *filePath = [path stringByAppendingPathComponent:@"array.plist"];
NSLog(@"%@",filePath);
//把數(shù)組寫入到沙盒當(dāng)中.
[array writeToFile:filePath atomically:YES];
-
讀取
注意:讀取的數(shù)據(jù)類型要以存儲(chǔ)的plist文件的最外層的數(shù)據(jù)類型相同,否則不能成功
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
//拼接文件名
NSString *filePath = [path stringByAppendingPathComponent:@"array.plist"];
NSArray *array = [NSArray arrayWithContentsOfFile:filePath];
NSLog(@"%@",array);
注意:不能存儲(chǔ)自定義的模型或?qū)ο?以下代碼無法將設(shè)置的字典數(shù)據(jù)寫大指定的路徑
Person *per = [[Person alloc] init];
per.name = @"xmg";
per.age = 12;
NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
NSString *filePath = [path stringByAppendingPathComponent:@"dict.plist"];
NSLog(@"%@",filePath);
NSDictionary *dict = @{@"per" : per,@"age" : @20};
[dict writeToFile:filePath atomically:YES];
2.偏好設(shè)置(也是以plist文件的形式存儲(chǔ))
同plist存儲(chǔ)方式相同,也只能存儲(chǔ)系統(tǒng)識(shí)別的格式(不能存儲(chǔ)自定義模型,對(duì)象等)
但是存儲(chǔ)的內(nèi)容與plist不同,存儲(chǔ)的內(nèi)容相對(duì)于plist來說較少,通常存儲(chǔ)系統(tǒng)版本信息,用戶名,密碼等
- 存儲(chǔ)
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"xmg" forKey:@"name"];
[defaults setInteger:20 forKey:@"age"];
[defaults setBool:YES forKey:@"isBool"];
- 讀取
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *name = [defaults objectForKey:@"name"];
NSInteger age = [defaults integerForKey:@"age"];
BOOL isBool = [defaults boolForKey:@"isBool"];
3.歸檔
存儲(chǔ)相對(duì)較大的文件,歸檔要求被存取的對(duì)象遵守NSCoding協(xié)議,并實(shí)現(xiàn)initWithCode和encodingWithCode方法,歸檔可以存儲(chǔ)任何數(shù)據(jù)
- 存儲(chǔ)
Person *per = [[Person alloc] init];
per.name = @"xmg";
per.age = 12;
//獲取文件路徑
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
//存儲(chǔ)的文件的文件名和后綴可以隨意起,但一般要起有意義的名稱
NSString *filePath = [path stringByAppendingPathComponent:@"per.data"];
//底層會(huì)自動(dòng)調(diào)用encodeWithCoder:方法,問下,要保存定義的對(duì)象哪些屬性
[NSKeyedArchiver archiveRootObject:per toFile:filePath];
**注意: **這里需要在Person類中實(shí)現(xiàn)initWithCode方法,以存儲(chǔ)想要存儲(chǔ)的數(shù)據(jù)
//Person類中的.m文件
//問下,要讀取對(duì)象哪些屬性
-(void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeInt:self.age forKey:@"age"];
}
- 讀取
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *filePath = [path stringByAppendingPathComponent:@"per.data"];
//unarchiveObjectWithFile:底層會(huì)自動(dòng)調(diào)用initWithCoder:方法,問下,要讀取對(duì)象哪些屬性
Person *per = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
**注意: **這里需要在Person類中實(shí)現(xiàn)encodeWithCoder方法,以讀取想要讀取的數(shù)據(jù)
//Person類的.m文件
//保存當(dāng)前對(duì)象的哪些屬性.
-(instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {//這里之所以沒有調(diào)用父類的initWithCoder方法,是因?yàn)楦割悰]有遵守NSCoding協(xié)議
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntForKey:@"age"];
}
return self;
}
歸檔注意點(diǎn):
- 1.如果被歸檔的對(duì)象里面有另一個(gè)對(duì)象,那么這個(gè)對(duì)象的對(duì)象也要遵守NSCoding協(xié)議
- 2.在開發(fā)中,dealloc方法中,不會(huì)寫任何代碼,所以不能再dealloc中進(jìn)行歸檔