###一、本地持久化 所謂的持久化,就是將資料儲存到硬碟中,使得在應用程式或機器重啟後可以繼續訪問之前儲存的資料。在iOS開發中,有很多資料持久化的方案,接下來我將嘗試著介紹一下5種方案:
- plist檔案(序列化)
- preference(偏好設定)
- NSKeyedArchiver(歸檔)
- SQLite3
- CoreData
本節我就只寫關於歸檔、偏好設定和屬性列表的,這些都是小資料持久化常用的方式,SQLite3和CoreData都是資料庫大資料儲存的方式,以後再寫。
###二、沙盒 在介紹各種儲存方法之前,有必要說明以下沙盒機制。iOS程式預設情況下只能訪問程式自己的目錄,這個目錄被稱為“沙盒”。
既然沙盒就是一個資料夾,那就看看裡面有什麼吧。沙盒的目錄結構如下:
應用程式包
:存放的是應用程式的原始檔,包括資原始檔和可執行檔案
NSString *path = [[NSBundle mainBundle] bundlePath];
複製程式碼
Documents
:最常用的目錄,iTunes同步該應用時會同步此資料夾中的內容,適合儲存重要資料
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject;
複製程式碼
Library
Caches
:iTunes不會同步此資料夾,適合儲存體積大,不需要備份的非重要資料。
NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES).firstObject;
複製程式碼
Preferences
:iTunes同步該應用時會同步此資料夾中的內容,通常儲存應用的設定資訊。tmp
: iTunes不會同步此資料夾,系統可能在應用沒執行時就刪除該目錄下的檔案,所以此目錄適合儲存應用中的一些臨時檔案,用完就刪除。
NSString *path = NSTemporaryDirectory();
複製程式碼
###三、plist檔案(序列化) plist檔案是將某些特定的類,通過XML檔案的方式儲存在目錄中。 ######可以被序列化的型別只有如下幾種:
NSArray;//陣列
NSMutableArray;//可變陣列
NSDictionary;//字典
NSMutableDictionary;//可變字典
NSData;//二進位制資料
NSMutableData;//可變二進位制資料
NSString;//字串
NSMutableString;//可變字串
NSNumber;//基本資料
NSDate;//日期
複製程式碼
######以NSArray為例,其他類使用方法完全相似:
- (void)writeToPlist{
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject;
NSString *fileName = [path stringByAppendingPathComponent:@"123.plist"];
NSArray *array = @[@"1234", @"tony", @"java"];
//序列化,把陣列存入plist檔案
[array writeToFile:fileName atomically:YES];
}
- (NSArray *)readFromPlist{
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject;
NSString *fileName = [path stringByAppendingPathComponent:@"123.plist"];
//反序列化,把plist檔案資料讀取出來,轉為陣列
NSArray *result = [NSArray arrayWithContentsOfFile:fileName];
NSLog(@"%@", result);
return result;
}
複製程式碼
儲存時使用
writeToFile:atomically:
方法。 其中atomically
表示是否需要先寫入一個輔助檔案,再把輔助檔案拷貝到目標檔案地址。這是更安全的寫入檔案方法,一般都寫YES
。
###四、Preference(偏好設定)
偏好設定是專門用來儲存應用程式的配置資訊的,一般不要在偏好設定中儲存其他資料。
偏好設定是以key-value
的方式進行儲存和讀寫,使用到一個單例物件NSUserDefaults
######下面是使用方法:
//1.獲得NSUserDefaults檔案
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
//2.向偏好設定中寫入內容
[userDefaults setObject:@"AAA" forKey:@"a"];
[userDefaults setBool:YES forKey:@"sex"];
[userDefaults setInteger:21 forKey:@"age"];
//2.1立即同步
[userDefaults synchronize];
//3.讀取偏好設定
NSString *name = [userDefaults objectForKey:@"a"];
BOOL sex = [userDefaults boolForKey:@"sex"];
NSInteger age = [userDefaults integerForKey:@"age"];
NSLog(@"%@, %d, %ld", name, sex, age);
複製程式碼
- 如果沒有呼叫
synchronize
方法,系統會根據I/O情況不定時刻地儲存到檔案中。所以如果需要立即寫入檔案的就必須呼叫synchronize
方法。
- 偏好設定會將所有資料儲存到同一個檔案中,使用同一個
key
進行儲存資料,會覆蓋之前儲存的資料。
###五、歸檔和解檔
歸檔在iOS中是另一種形式的序列化,只要遵循了NSCoding協議
的物件都可以通過它實現序列化。由於絕大多數支援儲存資料的類都遵循了NSCoding協議
,因此,對於大多數類來說,歸檔相對而言還是比較容易實現的。
####1. 遵循NSCoding協議
######NSCoding
協議宣告瞭兩個方法,這兩個方法都是必須實現的:
encodeWithCoder
:用來說明如何將物件編碼到歸檔中。initWithCoder
:用來說明如何進行解檔來獲取一個新物件。
//1.遵循NSCoding協議
@interface Person : NSObject <NSCoding>
//2.設定屬性
@property (strong, nonatomic) UIImage *avatar;
@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) NSInteger age;
@end
@implementation Person
//解檔
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
self.avatar = [aDecoder decodeObjectForKey:@"avatar"];
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
}
return self;
}
//歸檔
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.avatar forKey:@"avatar"];
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeInteger:self.age forKey:@"age"];
}
@end
複製程式碼
####2. NSKeyedArchiver歸檔
呼叫NSKeyedArchiver
的archiveRootObject:toFile:
方法把物件歸檔
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject;
NSString *file = [path stringByAppendingPathComponent:@"person.data"];
Person *person = [[Person alloc] init];
person.avatar = [UIImage imageNamed:@"icon.png"];
person.name = @"Xiao Ming";
person.age = 17;
[NSKeyedArchiver archiveRootObject:person toFile:file];
複製程式碼
####3. NSKeyedUnarchiver解檔
呼叫NSKeyedUnarchiver
的unarchiveObjectWithFile:
方法從檔案中解檔物件
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject;
NSString *file = [path stringByAppendingPathComponent:@"person.data"];
Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:file];
if (person) {
self.avatarView.image = person.avatar;
self.nameField.text = person.name;
self.ageField.text = [NSString stringWithFormat:@"%ld", person.age];
}
複製程式碼
- 必須遵循並實現NSCoding協議
- 儲存檔案的副檔名可以任意指定
- 繼承時必須先呼叫父類的歸檔解檔方法,這裡因為父類是NSObject,就不用了
以上就是小資料持久化的3種常用方法,下一節我將繼續寫大資料持久化的常用方法,敬請期待!!下面來個美女,沒配圖強迫症發作!
######如果喜歡,請點關注,如果不喜歡,請點喜歡,O(∩_∩)O哈!