iOS中的數據持久化方式,基本上有如下四種: 屬性列表、對象歸檔、SQLite3和Core Data 1.屬性列表 涉及到的主要類:NSUserDefaults,通常 [NSUserDefaults standardUserDefaults]就夠用了 @interface User : NSObject <NSCoding> @property (nonatomic, assign) NSInteger userID; @property (nonatomic, copy) NSString *name; @end 使用方法 1).分開存取 // 存 [[NSUserDefaults standardUserDefaults] setInteger:userID forKey:@」userID」]; [[NSUserDefaults standardUserDefaults] setObject:name forKey:@」name」]; // 取 NSInteger uId = [[[NSUserDefaults standardUserDefaults] integerValueForKey:@」userID」]; NSString* name = [[NSUserDefaults standardUserDefaults] stringForKey:@」name」]; 2).按對象存取 // 存 [[NSUserDefaults standardUserDefaults] setObject:self forKey:@」user」]; // 取 User* u = [[NSUserDefaults standardUserDefaults] objectForKey」@」user」]; 2.對象歸檔 要使用對象歸檔,對象必須實現NSCoding協議.大部分Object C對象都符合NSCoding協議,也能夠在自定義對象中實現NSCoding協議,要實現NSCoding協議,實現兩個方法: - (void) encodeWithCoder:(NSCoder *)encoder 與 -(void)initWithCoder:(NSCoder *)encoder 同時,建議對象也同時實現NSCopying協議,該協議容許複製對象,要實現NSCopying協議須實現 -(id)copyWithZone:(NSZone *)zone 方法 。 @interface User : NSObject <NSCoding> @property (nonatomic, assign) NSInteger userID; @property (nonatomic, copy) NSString *name; @end @implementation User // 如下兩個方法必定要實現,否則在調用的時候會crash - (void)encodeWithCoder:(NSCoder *)aCoder; { // 這裏放置須要持久化的屬性 [aCoder encodeObject:[NSNumber numberWithInteger:self.userID] forKey:@」userID」]; [aCoder encodeObject:self.name forKey:@"name"]; } - (id)initWithCoder:(NSCoder *)aDecoder { if (self = [self init]) { // 這裏務必和encodeWithCoder方法裏面的內容一致,否則會讀不到數據 self.userID = [[aDecoder decodeObjectForKey:@"userID"] integerValue]; self.name = [aDecoder decodeObjectForKey:@"name"]; } return self; } // 使用方法 + (BOOL)save { NSError *error = nil; // 肯定存儲路徑,通常是Document目錄下的文件 NSString* fileName = [self getFileName]; NSString* filePath = [self getFilePath]; if (![[NSFileManager defaultManager] createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:&error]) { NSLog(@」建立用戶文件目錄失敗」); return NO; } return [NSKeyedArchiver archiveRootObject:self toFile:[fileName:userId]]; } @end 3.SQLite3 SQLite是一個開源的嵌入式關係數據庫,它在2000年由D. Richard Hipp發佈,它的減小應用程序管理數據的開銷,SQLite可移植性好,很容易使用,很小,高效並且可靠。 SQLite嵌入到使用它的應用程序中,它們共用相同的進程空間,而不是單獨的一個進程。從外部看,它並不像一個RDBMS,但在進程內部,它倒是完整的,自包含的數據庫引擎。 嵌入式數據庫的一大好處就是在你的程序內部不須要網絡配置,也不須要管理。由於客戶端和服務器在同一進程空間運行。SQLite 的數據庫權限只依賴於文件系統,沒有用戶賬戶的概念。SQLite 有數據庫級鎖定,沒有網絡服務器。它須要的內存,其它開銷很小,適合用於嵌入式設備。你須要作的僅僅是把它正確的編譯到你的程序。 關於SQLite的開發資料較多,這裏再也不細說。只是建議不直接操做SQLite庫,而是採用一些開源的第三方庫來進行操做。好比: FMDB:https://github.com/ccgus/fmdb.git 對SQLite都作了不錯的封裝。 4.Core Data Core Data本質上是使用SQLite保存數據,可是它不須要編寫任何SQL語句。 要使用Core Data,須要在Xcode中的數據模型編輯器中設計好各個實體以及定義好他們的屬性和關係。以後,經過操做這些對象,結合Core Data完成數據的持久化: NSManagedObjectContext *context = [appDelegate managedObjectContext]; NSError *error; NSString *fieldName = [NSString stringWithFormat:@"test%d", i]; UITextField *theField = [self valueForKey:fieldName]; NSFetchRequest *request = [[NSFetchRequest alloc] init]; //創 建描述語句,需求Line對象。相似於在數據庫中限定爲Line表。 NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Line" inManagedObjectContext:context]; [request setEntity:entityDescription]; //建立限制性語句,相似於SQL語句中的 where lineNum = i NSPredicate *pred = [NSPredicate predicateWithFormat:@"(lineNum = %d)", i]; [request setPredicate:pred]; NSManagedObject *theLine = nil; NSArray *objects = [context executeFetchRequest:request error:&error]; if (objects == nil){ NSLog(@」There was an error!」); // Do whatever error handling is appropriate } if ([objects count] > 0){ //若是符合條件的object存在,則取出 theLine = [objects objectAtIndex:0]; } else { //若是不存在,則插入一個新的. theLine = [NSEntityDescription insertNewObjectForEntityForName:@"Line" inManagedObjectContext:context]; [theLine setValue:[NSNumber numberWithInt:i] forKey:@」lineNum」]; //設置這個object的屬性,coredata會自動將其寫入sqlite [theLine setValue:theField.text forKey:@"lineText"]; [request release]; } } 下面是其取數據的過程。 Core_Data_PersistenceAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; NSManagedObjectContext *context = [appDelegate managedObjectContext]; NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Line" inManagedObjectContext:context]; NSFetchRequest *request = [[NSFetchRequest alloc] init]; [request setEntity:entityDescription]; NSError *error; NSArray *objects = [context executeFetchRequest:request error:&error]; if (objects == nil) { NSLog(@」There was an error!」); // Do whatever error handling is appropriate } //每個對象在CoreData中都表示爲一個NSManagedObject對象(相似於數據庫表中的每一行),他的屬性經過鍵/值 方式獲取 for (NSManagedObject *oneObject in objects) { NSNumber *lineNum = [oneObject valueForKey:@"lineNum"]; NSString *lineText = [oneObject valueForKey:@"lineText"]; } [request release];