1鸿市、概念
數(shù)據(jù)持久化-將數(shù)據(jù)保存在硬盤(pán)中荸频,使得機(jī)器/應(yīng)用程序重啟后,可以繼續(xù)訪問(wèn)之前保存的數(shù)據(jù)籽腕。
2珠移、方案
plist(屬性列表)弓乙、preference(偏好設(shè)置)、NSKeyedArchiver(歸檔)钧惧、SQLite 3(數(shù)據(jù)庫(kù))暇韧、CoreData
3、沙盒機(jī)制
3.1浓瞪、應(yīng)用程序的目錄路經(jīng)
NSString *appPath = NSHomeDirectory();
appPath:/Users/lizhongfeng/Library/Developer/CoreSimulator/Devices/6E35AB76-8538-4BB8-9F2A-1574A807C05B/data/Containers/Data/Application/39D4B302-E8BA-4DC0-A9A2-E47DCCD89615
上面的代碼得到的是app的目錄路徑懈玻,即為該app的沙盒路徑。
3.2乾颁、沙盒的目錄結(jié)構(gòu)
雖然沙盒中文件夾較多涂乌,但這些文件夾不盡相同,所存放的數(shù)據(jù)類型不同英岭。因此湾盒,存放數(shù)據(jù)時(shí),應(yīng)根據(jù)數(shù)據(jù)類型和想要達(dá)到的效果诅妹,選擇合適的文件夾罚勾。
3.2.1、Documents
最常用的目錄吭狡,iTunes同步該應(yīng)用時(shí)尖殃,會(huì)同步此文件夾中的內(nèi)容,適合存儲(chǔ)重要數(shù)據(jù)划煮;
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
documentsPath:/Users/lizhongfeng/Library/Developer/CoreSimulator/Devices/6E35AB76-8538-4BB8-9F2A-1574A807C05B/data/Containers/Data/Application/0967BD85-9B06-449B-A1F0-27B542BAC69A/Documents
3.2.2送丰、Library/Caches
iTunes不會(huì)同步此文件夾,適合存儲(chǔ)體積大弛秋,但無(wú)需備份的非重要數(shù)據(jù)器躏;
NSString *cachesPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
cachesPath:/Users/lizhongfeng/Library/Developer/CoreSimulator/Devices/6E35AB76-8538-4BB8-9F2A-1574A807C05B/data/Containers/Data/Application/0967BD85-9B06-449B-A1F0-27B542BAC69A/Library/Caches
3.2.3、Library/Preferences
iTunes同步該應(yīng)用時(shí)蟹略,會(huì)同步此文件夾中的內(nèi)容登失,通常保存應(yīng)用的設(shè)置信息;
3.2.4科乎、tmp
iTunes不會(huì)同步此文件夾壁畸,系統(tǒng)可能在應(yīng)用沒(méi)運(yùn)行時(shí),就刪除該目錄下的文件,所以該目錄適合保存應(yīng)用中的一些臨時(shí)文件捏萍,用完就刪除太抓。
NSString *tmpPath = NSTemporaryDirectory();
tmpPath:/Users/lizhongfeng/Library/Developer/CoreSimulator/Devices/6E35AB76-8538-4BB8-9F2A-1574A807C05B/data/Containers/Data/Application/5A198C87-225D-4263-BCDF-9CC28A9DFB4F/tmp/
4、plist文件
plist文件是將某些類令杈,通過(guò)XML文件的形式保存在目錄中走敌。
4.1、可以被序列化的類型
NSArray/NSMutableArray逗噩、NSDictionary/NSMutableDictionary掉丽、NSData/NSMutableData、NSString/NSMutableString异雁、NSNumber捶障、NSDate,只有以上類型才能使用plist文件存儲(chǔ)纲刀。
4.2项炼、存儲(chǔ)步驟
// 拼接文件路徑
NSString *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *filePath = [docPath stringByAppendingPathComponent:@"123.plist"];
// 存儲(chǔ)
NSArray *array = @[@"123",@"456",@"zhongfeng"];
[array writeToFile:filePath atomically:YES];
// 讀取
NSArray *result = [NSArray arrayWithContentsOfFile:filePath];
NSLog(@"result:%@",result);
注意:
存儲(chǔ)時(shí)使用writeToFile: atomically:方法。其中示绊,atomically:表示是否先寫(xiě)入一個(gè)臨時(shí)文件锭部,再將該臨時(shí)文件拷貝到目標(biāo)文件地址。將其設(shè)置為YES是一種更安全的文件寫(xiě)入方法面褐,所以一般都寫(xiě)YES拌禾。
讀取文件使用***WithContentsOfFile:(arrayWithContentsOfFile:,dictionaryWithContentsOfFile:)方法展哭。
5湃窍、Preference
5.1、使用方法
// 獲得NSUserDefaults文件
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
// 項(xiàng)文件中寫(xiě)入內(nèi)容
[userDefault setObject:@"zhongfeng" forKey:@"name"];
[userDefault setInteger:27 forKey:@"age"];
[userDefault setBool:YES forKey:@"isMan"];
// 同步(手動(dòng)調(diào)用synchronize方法以及時(shí)保存userDefault文件內(nèi)容)
[userDefault synchronize];
// 讀取
NSString *name = [userDefault stringForKey:@"name"];
NSInteger age = [userDefault integerForKey:@"age"];
BOOL isMan = [userDefault boolForKey:@"isMan"];
NSLog(@"name = %@, age = %ld, isMan = %d",name,(long)age,isMan);
注意:
偏好設(shè)置一般是用來(lái)保存應(yīng)用程序的配置信息摄杂,不要在偏好設(shè)置中保存其他數(shù)據(jù)坝咐。
如果沒(méi)有調(diào)用synchronize方法進(jìn)行同步循榆,則NSUserDefaults會(huì)過(guò)一段時(shí)間自動(dòng)調(diào)用synchronize方法進(jìn)行同步析恢。因此,如果需要立即寫(xiě)入文件就必須馬上調(diào)用synchronize方法秧饮。
偏好設(shè)置會(huì)將所有數(shù)據(jù)保存在Preferences中一個(gè)以應(yīng)用程序包名(Bundle Identifier)的plist文件映挂。因此,偏好設(shè)置所能存儲(chǔ)的數(shù)據(jù)類型肯定是plist文件所支持的類型盗尸。
6柑船、NSKeyedArchiver
歸檔是iOS中另一種形式化的序列化,只要遵循了NSCoding協(xié)議的對(duì)象都可以通過(guò)它實(shí)現(xiàn)序列化泼各。由于絕大數(shù)支持存儲(chǔ)數(shù)據(jù)的Foundation和Coca? Touch類都遵循了NSCoding協(xié)議鞍时。因此,對(duì)于大多數(shù)類而言,歸檔還是比較容易實(shí)現(xiàn)逆巍。
6.1及塘、NSCoding
NSCoding協(xié)議聲明了兩個(gè)方法,這兩個(gè)方法都必須要實(shí)現(xiàn)锐极。一個(gè)方法說(shuō)明如何將對(duì)象編碼到歸檔中笙僚;另一個(gè)方法說(shuō)明如何解檔獲取一個(gè)對(duì)象。
/*遵循協(xié)議灵再、設(shè)置屬性*/
#import@interface Person : NSObject// 遵循NSCoding協(xié)議
// 屬性
@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) NSInteger age;
@property (nonatomic,assign) BOOL isMan;
// 初始化Person
+(instancetype)initPersonWithName:(NSString *)name age:(NSInteger)age isMan:(BOOL)isMan;
@end
/*實(shí)現(xiàn)NSCoding的兩個(gè)方法*/
#import "Person.h"
@implementation Person
// 解檔
-(instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
self.isMan = [aDecoder decodeBoolForKey:@"isMan"];
}
return self;
}
// 歸檔
-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeInteger:self.age forKey:@"age"];
[aCoder encodeBool:self.isMan forKey:@"isMan"];
}
注意:
如果需要?dú)w檔的類是某個(gè)自定義類的子類時(shí)肋层,就需要在歸檔和解檔之前先調(diào)用父類的[super initWithCoder:aDecoder]和[super encodeWithCoder:aCoder]方法;
/*使用*/
歸檔對(duì)象是調(diào)用NSKeyedArchiver的類方法archiveRootObject: toFile:方法翎迁,解檔對(duì)象是調(diào)用NSKeyedUnarchiver的類方法unarchiveObjectWithFile:方法栋猖。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 創(chuàng)建文件保存路徑
NSString *personInfoPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"personInfo.data"];
// 實(shí)例化一個(gè)person
Person *person = [Person initPersonWithName:@"宣曉" age:27 isMan:NO];
// 歸檔
[self archiverPerson:person filePath:personInfoPath];
// 解檔
[self unarchiverPersonWithFilePath:personInfoPath];
}
#pragma mark - 歸檔對(duì)象
-(void)archiverPerson:(Person *)person filePath:(NSString *)filePath
{
// 歸檔
[NSKeyedArchiver archiveRootObject:person toFile:filePath];
}
#pragma mark - 解檔對(duì)象
-(void)unarchiverPersonWithFilePath:(NSString *)filePath
{
// 解檔
Person *person2 = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
if (person2) {
NSLog(@"name:%@,age:%ld,isMan:%d",person2.name,(long)person2.age,person2.isMan);
}
}
注意:
使用歸檔和解檔的類,必須遵循并實(shí)現(xiàn)NSCoding協(xié)議汪榔;
所保存文件的擴(kuò)展名可以任意指定掂铐;
若有繼承,必須先調(diào)用父類的歸檔和解檔方法揍异。