標籤:
IOS開發中資料持久化的幾種方法--NSUserDefaults
IOS 開發中,經常會遇到需要把一些資料儲存在本地的情況,那麼這個時候我們有以下幾種可以選擇的方案:
一、使用NSUserDefault是最簡單直接的一個辦法:
1)儲存資料:
1 // 執行個體化一個NSUserDefaults單例對象2 NSUserDefaults *user = [NSUserDefaults standardUserDefaults];3 // 把一個數組array儲存在key為allContact的索引值對裡4 [user setObject:array forKey:@"allContact"];5 // 直接寫入硬碟6 [user synchronize];
2)讀取資料:
1 // 執行個體化一個NSUserDefaults單例對象2 NSUserDefaults *user = [NSUserDefaults standardUserDefaults];3 // 把儲存在裡面的array根據key為allContact拿出來4 NSArray *dataarray = [user objectForKey:@"allContact"];
注意事項:
在蘋果的官方文檔有明確說明:
也就是說,只能存入 NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. For NSArray and NSDictionary objects, their contents must be property list objects.這些對象,而且(. For NSArray and NSDictionary objects, their contents must be property list objects.)比如數組,字典中存的元素也只能是以上這些對象的內容,那如何把自訂的一個比較複雜的類的執行個體對象使用NSUserDefaults儲存呢?方法如下:
以一個手機連絡人類myContact為例說明:
1)在myContact.h檔案中讓類遵守NSCoding協議:
1 // 2 // myContact.h 3 // 老年人電話本 4 // 5 // Created by mac on 16/5/3. 6 // Copyright © 2016年 mzw. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h>10 11 //要使用單例NSUserDefault來儲存自訂對象,首先要讓自訂的對象遵守NSCoding協議12 @interface myContact : NSObject<NSCoding>13 14 @property(nonatomic, copy)NSString *firstname;15 @property(nonatomic, copy)NSString *lastname;16 @property(nonatomic, copy)NSString *phoneNumber;17 @property(nonatomic, copy)NSData *photo;18 @property(nonatomic, copy)NSString *identify;19 @property(nonatomic, assign)BOOL emergency;20 21 @end
2)在myContact.m檔案中實現兩個方法:encodeWithCoder 和 initWithCoder方法
1 // 2 // myContact.m 3 // 老年人電話本 4 // 5 // Created by mac on 16/5/3. 6 // Copyright © 2016年 mzw. All rights reserved. 7 // 8 9 #import "myContact.h"10 11 @implementation myContact12 13 @synthesize firstname;14 @synthesize lastname;15 @synthesize phoneNumber;16 @synthesize photo;17 @synthesize identify;18 @synthesize emergency;19 20 -(void)encodeWithCoder:(NSCoder *)aCoder{21 22 [aCoder encodeObject:self.firstname forKey:@"firstname"];23 [aCoder encodeObject:self.lastname forKey:@"lastname"];24 [aCoder encodeObject:self.phoneNumber forKey:@"phoneNumber"];25 [aCoder encodeObject:self.photo forKey:@"photo"];26 [aCoder encodeObject:self.identify forKey:@"identify"];27 [aCoder encodeBool:self.emergency forKey:@"emergency"];//注意對於布爾類型的不能使用encodeObject,而要對應的使用encodeBool。28 }29 30 -(id)initWithCoder:(NSCoder *)aDecoder{31 32 if (self = [super init]) {33 34 self.firstname = [aDecoder decodeObjectForKey:@"firstname"];35 self.lastname = [aDecoder decodeObjectForKey:@"lastname"];36 self.phoneNumber = [aDecoder decodeObjectForKey:@"phoneNumber"];37 self.photo = [aDecoder decodeObjectForKey:@"photo"];38 self.identify = [aDecoder decodeObjectForKey:@"identify"];39 self.emergency = [aDecoder decodeBoolForKey:@"emergency"];//同理此處要對應的使用decodeBoolForKey。40 }41 return self;42 }
3)完成以上兩步,我們就可以通過NSUserDefaults來儲存myContact的執行個體對象了:(以下程式段既涉及到讀取,又涉及到追加內容後儲存)
1 // 屬性值賦值完成後就可以使用NSKeyedArchiver把對象mycontact1打包為一個NSData對象 2 NSData *data = [NSKeyedArchiver archivedDataWithRootObject:mycontact1]; 3 // 建立並初始化一個NSUserDefaults單例對象 4 NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; 5 // 先讀取user之前存進去的allContact所對應的值(是一個不可變的數組),然後因為我們要給這個數組追加一個連絡人的打包後的NSData資料,所以要把這個數群組轉換成為一個可變數組。 6 NSMutableArray *contactarray = [NSMutableArray arrayWithArray:[user objectForKey:@"allContact"]]; 7 // 把之前打包好的連絡人mycontact1的NSData資料追加到可變數組contactarray中 8 [contactarray addObject:data]; 9 // 再把這個可變數群組轉換為一個不可變數組10 NSArray *array = [NSArray arrayWithArray:contactarray];11 // 使用相同的key值儲存新的array,之前allContact對應的值被替換12 [user setObject:array forKey:@"allContact"];13 // 直接寫入硬碟14 [user synchronize];
注意:通過NSUserDefaults儲存的資料是全域的,這也為我們提供了一個管理全域變數的手段,比如在頁面A儲存了一些資料,在其他很多頁面都要用到,那我們可以通過單例來儲存,這樣就可以在不同的頁面中通過同個NSUserDefaults的key值去讀取對應的內容。但這樣的操作要注意,儲存的資料一定是不可變的,不能是可變的數組、可變字串、可變字典等,否則程式會產生不可預期的錯誤。
IOS開發中資料持久化的幾種方法--NSUserDefaults