OC有多種數(shù)據(jù)持久化得方式
Write寫入方式(nsstring,data,nsdictionary,nsarray)
preference(偏好設(shè)置近范,NSUserDefaults样悟,屬性)(nsstring,nsnumber,nsdata,nsdate,nsarray,nsdictionary)
NSKeyedArchiver(歸檔,用的不多)
SQLite 3 (需要導(dǎo)入庫libsqlite3.0.tbd伤极,并且在使用時(shí)要包含
頭文件)
CoreData (IOS5后出的框架,能幫助我們不寫SQL語句將數(shù)據(jù)保存在SQLite數(shù)據(jù)庫文件中泻轰,并對(duì)數(shù)據(jù)進(jìn)行管理)
下面看看coreData的使用方法
1.新建一個(gè)工程
(1)先不勾選Xcode為我們提供的Use Core Data,自己通過代碼創(chuàng)建一個(gè)數(shù)據(jù)庫
(2)進(jìn)到工程后新建文件莉御,選擇iOS->CoreData->Data Model,給這個(gè)Data Model取一個(gè)名字疙渣,保存
(3)創(chuàng)建好后工程中多出Model.xcdatamodeld文件匙奴,我們可以對(duì)這個(gè)文件進(jìn)行操作
(4)左下角有Add Entity按鈕,添加一個(gè)實(shí)體(相當(dāng)于數(shù)據(jù)庫中的表)妄荔。添加一個(gè)Entity,取名為Person
(5)選中Person,點(diǎn)擊右下角Add Attribute 或右邊Attribute欄目中點(diǎn)擊加號(hào)泼菌,
為Person添加屬性(我添加了name,age兩個(gè)屬性,設(shè)置其類型為string和integer16類型)
2.做好上述操作后到AppDelegate.m文件中寫寫創(chuàng)建代碼啦租,記得包含 頭文件哗伯;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
這個(gè)方法在程序加載完成后會(huì)調(diào)用
3.代碼創(chuàng)建SQLite數(shù)據(jù)庫
先理解幾個(gè)概念:
1.NSManagedObjectContext(負(fù)責(zé)應(yīng)用和數(shù)據(jù)庫的交互,所有對(duì)數(shù)據(jù)庫的操作都是通過它來完成的)
NSManagedObjectContext擁有一個(gè)NSPersistentStoreCoordinator類的實(shí)例對(duì)象
2.NSPersistentStoreCoordinator(用來添加持久化存儲(chǔ)庫篷角,這里是SQLite數(shù)據(jù)庫)
NSPersistentStoreCoordinator擁有一個(gè) NSManagedObjectModel類的實(shí)例對(duì)象
3. NSManagedObjectModel(CoreData的模型文件焊刹,本例中就是上面創(chuàng)建Model.xcdatamodeld的模型)
NSManagedObjectModel有entities(數(shù)組)這個(gè)屬性(本例中就是指Person,因?yàn)橹粍?chuàng)建了Person這一個(gè)實(shí)體,所以數(shù)組中就只有這一個(gè)元素)
4.NSManagedObject(對(duì)象模型恳蹲,例如下面代碼中要新建的personOne)
5.NSEntityDescription(用來描述實(shí)體)想要添加到數(shù)據(jù)庫的模型不能用alloc init 來創(chuàng)建虐块,只能用NSEntityDescription來描述
//構(gòu)建路徑,獲取到沙盒里的Documents路徑
NSURL*documentURL = [[[NSFileManagerdefaultManager] URLsForDirectory:NSDocumentDirectoryinDomains:NSUserDomainMask] lastObject];
//打印沙盒路徑,方便后面查看
NSLog(@"%@",documentURL);
//經(jīng)過編譯后數(shù)據(jù)模型文件的擴(kuò)展名由xcdatamodeld變成了momd
NSURL*modelURL = [[NSBundlemainBundle] URLForResource:@"Model"withExtension:@"momd"];
//構(gòu)建CoreData的模型文件阱缓,就是Model.xcdatamodeld的模型
NSManagedObjectModel*managedModel = [[NSManagedObjectModelalloc] initWithContentsOfURL:modelURL];
//通過模型文件創(chuàng)建PersistentStoreCoordinator對(duì)象非凌,
NSPersistentStoreCoordinator*persistStore = [[NSPersistentStoreCoordinatoralloc] initWithManagedObjectModel:managedModel];
//構(gòu)造數(shù)據(jù)庫存儲(chǔ)路徑URL
NSURL*persistStoreURL = [documentURL URLByAppendingPathComponent:@"Model.sqlite"];
//設(shè)置persistStore的持久化存儲(chǔ)方式為SQLiteStoreType,代表persistStore會(huì)自動(dòng)生成一個(gè)SQLite數(shù)據(jù)庫文件來實(shí)現(xiàn)持久化存儲(chǔ)举农,并會(huì)自動(dòng)生成SQL語句來做CRUD(增刪改查)
[persistStore addPersistentStoreWithType:NSSQLiteStoreTypeconfiguration:nilURL:persistStoreURL options:nilerror:nil];
//NSManagedObjectContext:所有的ManagedObject的CRUD都是在context上進(jìn)行的荆针。
//NSMainQueueConcurrencyType:這個(gè)context所關(guān)聯(lián)的控制器和UI控件只能在主線程中使用
NSManagedObjectContext*managerContext = [[NSManagedObjectContextalloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
//建立persistStore和context的關(guān)聯(lián)
[managerContext setPersistentStoreCoordinator:persistStore];
//創(chuàng)建需要保存的對(duì)象personOne
NSManagedObject*personOne = [NSEntityDescriptioninsertNewObjectForEntityForName:@"Person"inManagedObjectContext:managerContext];
//設(shè)置personOne的屬性,這里personOne和我們平常用的person實(shí)例有一點(diǎn)區(qū)別,它無法通過點(diǎn)語法直接拿到屬性(后面有解決方法)航背,只能通過KVC來設(shè)置它的屬性
[personOne setValue:@23forKey:@"age"];
[personOne setValue:@"wl"forKey:@"name"];
//保存數(shù)據(jù)
if([managerContext save:nil])
{
NSLog(@"保存數(shù)據(jù)成功");
}
4.運(yùn)行喉悴,可以看到如下打印結(jié)果
5.復(fù)制路徑去沙盒里查看,注意復(fù)制的時(shí)候路徑的正確性,去掉前面的file://
6.可以看到數(shù)據(jù)庫已經(jīng)創(chuàng)建成功玖媚,打開數(shù)據(jù)庫可以看到數(shù)據(jù)也已經(jīng)成功添加了(SQLiteManager)
7.上面已經(jīng)完成了簡(jiǎn)單的數(shù)據(jù)庫創(chuàng)建箕肃,然而還是有一些問題
顯然personOne的屬性通過KVC的方式設(shè)置不太好,解決:我們可以自己創(chuàng)建Person類來設(shè)置屬性今魔,CoreData為我們提供了一種簡(jiǎn)單的方法
3.接下來就是與Xcode 7 以及以前版本不同的地方了勺像,創(chuàng)建NSManagedObject SubClass文件
xcode8新版本
選中Person 這個(gè)Entity,在頂部狀態(tài)欄中點(diǎn)擊創(chuàng)建错森,特別注意:默認(rèn)創(chuàng)建的是swift吟宦,如果要?jiǎng)?chuàng)建OC的,需要修改一下語言選擇
ToosVersion最好選擇8.0涩维,當(dāng)然殃姓,選擇7.3也是沒有問題的,創(chuàng)建會(huì)出現(xiàn)四個(gè)文件瓦阐,如圖所示:
xcode7老版本 ?command+n,選擇iOS->CoreData->NSmanagerObject subclass
8.next->勾選上dataModel-> next->勾選上Person創(chuàng)建蜗侈,系統(tǒng)會(huì)幫我們自動(dòng)生成4個(gè)文件
9.在AppDelegate.m中導(dǎo)入Person.h并修改代碼managerObject 部分代碼
修改前部分
//創(chuàng)建需要保存的對(duì)象personOne
NSManagedObject*personOne = [NSEntityDescriptioninsertNewObjectForEntityForName:@"Person"inManagedObjectContext:managerContext];
//設(shè)置personOne的屬性,這里personOne和我們平常用的person實(shí)例有一點(diǎn)區(qū)別睡蟋,它無法通過點(diǎn)語法直接拿到屬性(后面有解決方法)踏幻,只能通過KVC來設(shè)置它的屬性
[personOne setValue:@23forKey:@"age"];
[personOne setValue:@"wl"forKey:@"name"];
這部分替換成
Person *personTwo = [NSEntityDescriptioninsertNewObjectForEntityForName:@"Person"inManagedObjectContext:managerContext];
personTwo.age =@100;
personTwo.name = @"lw";
10.運(yùn)行,查看數(shù)據(jù)庫戳杀,數(shù)據(jù)也成功添加進(jìn)去了
也許你沒有那么順利:報(bào)錯(cuò)了:
發(fā)現(xiàn)報(bào)錯(cuò)了叫倍,錯(cuò)誤原因如下
我們?cè)谧钣覀?cè)的菜單欄中,將Codegen改為Manrual/None
這里豺瘤,如果還是報(bào)錯(cuò)吆倦,請(qǐng)將identity and type改為Core Data Model
并且將Class中的codege設(shè)置成Manua/None
Clean 完后 跑一下發(fā)現(xiàn)正常運(yùn)行,到此坐求,就配置完畢了蚕泽。
11.知道了整個(gè)過程后現(xiàn)在再新建一個(gè)工程看系統(tǒng)是勾選Use Core Data看看Xcode是如何實(shí)現(xiàn)的
(1)AppDelegate.h ?多出了3個(gè)屬性和2個(gè)方法,AppDelegate.m是實(shí)現(xiàn)過程(就不放上來了桥嗤,可以自己新建一個(gè)工程看须妻,思路是一致的,考慮的更全面泛领,
熟悉過程后創(chuàng)建可以直接copy系統(tǒng)的實(shí)現(xiàn)代碼荒吏。
@property(readonly, strong,nonatomic)NSManagedObjectContext*managedObjectContext;
@property(readonly, strong,nonatomic)NSManagedObjectModel*managedObjectModel;
@property(readonly, strong,nonatomic)NSPersistentStoreCoordinator*persistentStoreCoordinator;
- (void)saveContext;
- (NSURL*)applicationDocumentsDirectory;