前言
iOS本機快取資料方式有五種:
1.直接寫檔案方式:可以儲存的對象有NSString、NSArray、NSDictionary、NSData、NSNumber,資料全部存放在一個屬性列表檔案(*.plist檔案)中。
2.NSUserDefaults(喜好設定),用來儲存應用設定資訊,檔案放在perference目錄下。
3.歸檔操作(NSkeyedArchiver),不同於前面兩種,它可以把自訂對象存放在檔案中。
4.coreData:coreData是蘋果官方iOS5之後推出的綜合型資料庫,其使用了ORM(Object Relational Mapping)對象關係映射技術,將對象轉換成資料,儲存在本機資料庫中。coreData為了提高效率,甚至將資料存放區在不同的資料庫中,且在使用的時候將本機資料放到記憶體中使得訪問速度更快。我們可以選擇coreData的資料存放區方式,包括sqlite、xml等格式。但也正是coreData 是完全物件導向的,其在執行效率上比不上原生的資料庫。除此之外,coreData擁有資料驗證、undo等其他功能,在功能上是幾種持久化方案最多的。
5.FMDB:FMDB是iOS平台的SQLite資料庫架構,FMDB以OC的方式封裝了SQLite的C語言API,使用起來更加物件導向,省去了很多麻煩、冗餘的C語言代碼,對比蘋果內建的Core Data架構,更加輕量級和靈活,提供了多安全執行緒的資料庫操作方法,有效地防止資料混亂。 方式一:直接寫檔案
//擷取沙箱中快取檔案夾路徑
//方法一
//沙箱主目錄
NSString *homePath = NSHomeDirectory();
//拼接路徑
NSString *path = [homePath stringByAppendingPathComponent:@"Library/Caches"];
//方法二
//第一個參數目標檔案夾目錄(NSCachesDirectory尋找快取檔案夾),第二個參數為尋找目錄的域(NSUserDomainMask為在使用者目錄下尋找),第三個參數為結果中主目錄是否展開,不展開則顯示為~
NSArray *arr = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
//雖然該方法返回的是一個數組,但是由於一個目標檔案夾只有一個目錄,所以數組中只有一個元素。
NSString *cachePath = [arr lastObject];
//或者
// NSString *cachePath = [arr objectAtIndex:0];
/**
//擷取沙箱中Document檔案夾或者tmp檔案夾路徑都可使用上面兩種方法
//tmp檔案夾路徑可直接這樣擷取
NSString *tmpPath = NSTemporaryDirectory();
NSLog(@"%@",tmpPath);
**/
//拼接路徑(目標路徑),這個時候如果目錄下不存在這個lotheve.plist檔案,這個目錄實際上是不存在的。
NSString *filePath = [cachePath stringByAppendingPathComponent:@"tese.plist"];
NSLog(@"%@",filePath);
//建立資料
NSDictionary *content = @{@"字典資料測試1":@"1",@"字典資料測試2":@"2",@"字典資料測試":@"3"};
//將資料存到目標路徑的檔案中(這個時候如果該路徑下檔案不存在將會自動建立)
//用writeToFile方法寫檔案會覆蓋掉原來的內容
[content writeToFile:filePath atomically:YES];
//讀取資料(通過字典的方式讀出檔案中的內容)
NSDictionary *dic = [NSDictionary dictionaryWithContentsOfFile:filePath];
NSLog(@"%@",dic);
沙箱中Library/Caches目錄下多了lotheve.plist檔案:
檔案內容:
如何擷取模擬器沙箱路徑:
列印日誌,複製路徑開啟mac finder,點擊左上方菜單前往,前往檔案夾,把路徑粘貼上去。
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) objectAtIndex:0];
NSLog(@"%@",path); 方式二:NSUserDefaults(喜好設定)
每個應用都有一個NSUesrDefaults執行個體,通過它可以儲存應用配置資訊以及使用者資訊,比如儲存使用者名稱、密碼、字型大小、是否自動登入等等。資料自動儲存在沙箱的Libarary/Preferences目錄下。同樣,該方法只能存取NSString、NSArray、NSDictionary、NSData、NSNumber類型的資料。
屬性列表是一種明文的輕量級儲存方式,其儲存格式有多種,最常規格式為XML格式。在我們建立一個新的項目的時候,Xcode會自動產生一個info.plist檔案用來儲存項目的部分系統設定。plist只能用數組(NSArray)或者字典(NSDictionary)進行讀取,由於屬性列表本身不加密,所以安全性幾乎可以說為零。因為,屬性列表正常用於儲存少量的並且不重要的資料。
在程式啟動後,系統會自動建立一個NSUserDefaults的單例對象,我們可以擷取這個單例來儲存少量的資料,它會將輸出儲存在.plist格式的檔案中。其優點是像字典一樣的賦值方式方便簡單,但缺點是無法儲存自訂的資料。
程式碼範例:
//點擊button儲存資料
- (IBAction)saveData:(id)sender {
//擷取NSUserDefaults對象
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
//存資料,不需要設定路勁,NSUserDefaults將資料儲存在preferences目錄下
[userDefaults setObject:@"Lotheve" forKey:@"name"];
[userDefaults setObject:@"NSUserDefaults" forKey:@"demo"];
//立刻儲存(同步)資料(如果不寫這句話,會在將來某個時間點自動將資料儲存在preferences目錄下)
[userDefaults synchronize];
NSLog(@"資料已儲存");
}
//點擊button讀取資料
- (IBAction)getData:(id)sender
{
//擷取NSUserDefaults對象
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
//讀取資料
NSString *name = [userDefaults objectForKey:@"name"];
NSString *demo = [userDefaults objectForKey:@"demo"];
//列印資料
NSLog(@"name = %@ demo =%@",name,demo);
}
點擊“儲存資料”後,查看沙箱中的Libarary/ Preferences目錄:
資料以plist的格式寫入磁碟中了。點開查看資料:
方式三:NSKeyedArchiver(歸檔操作)
與屬性列表相反,同樣作為輕量級儲存的持久化方案,資料歸檔是進行加密處理的,資料在經過歸檔處理會轉換成位元據,所以安全性要遠遠高於屬性列表。另外使用歸檔方式,我們可以將複雜的對象寫入檔案中,並且不管添加多少對象,將對象寫入磁碟的方式都是一樣的。
使用NSKeyedArchiver對自訂的資料進行序列化,並且儲存在沙箱目錄下。使用這種歸檔的前提是讓儲存的資料模型遵守NSCoding協議並且實現其兩個協議方法。(當然,如果為了更加安全的儲存,也可以遵守NSSecureCoding協議,這是iOS6之後新增的特性)
使用歸檔操作儲存資料的主要好處是,不同於前面兩種方法只能儲存幾個常用的資料類型的資料,NSKeyedArchiver可以儲存自訂的對象。
程式碼範例:
先建立一個繼承NSObject的類,該類遵守NSCoding協議
TestPerson.h
@interface TestPerson : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, copy) NSString *sex;
@property (nonatomic, strong) NSArray *familyMumbers;
@end
TestPerson.m
#import "TestPerson.h"
@interface TestPerson ()
@end
@implementationTestPerson
- (void)viewDidLoad
{
[super viewDidLoad];
}
#pragma mark - NSCoding協議方法 (一定要實現)
//當進行歸檔操作的時候就會調用該方法
//在該方法中要寫清楚要儲存物件的哪些屬性
- (void)encodeWithCoder:(NSCoder *)aCoder
{
NSLog(@"調用了encodeWithCoder方法");
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeInteger:_age forKey:@"age"];
[aCoder encodeObject:_sex forKey:@"sex"];