iOS中的四種數據持久化方式

屬性列表、對象歸檔、SQLite3和Core Data

1.屬性列表涉及到的主要類:NSUserDefaults,一般 [NSUserDefaults? standardUserDefaults?]就夠用了

@interface User : NSObject@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@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];?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容