iOS編程CoreData的使用

oreData是iOS5后,蘋果提供的原生的用于對(duì)象化管理數(shù)據(jù)并且持久化的框架竿拆。CoreData本質(zhì)上是將底層數(shù)據(jù)庫封裝成對(duì)象進(jìn)行管理。但數(shù)據(jù)庫實(shí)際上只是CoreData的一個(gè)功能,并不是全部功能。在iOS開發(fā)中振定,除了可以使用CoreData進(jìn)行數(shù)據(jù)管理,還可以使用SQLite進(jìn)行內(nèi)存管理肉拓。并且有封裝好SQLite代碼的OC框架FMDB給我們使用后频。具體看我上篇文章。SQLite重要框架FMDB的使用.但對(duì)比SQLite,CoreData有下面幾個(gè)優(yōu)勢(shì)暖途。第一是CoreData作為蘋果提供的原生框架卑惜,在內(nèi)存方法比SQLite有性能上的優(yōu)勢(shì)。第二是CoreData操作數(shù)據(jù)不需要使用SQLite代碼驻售,使用方便露久。第三是CoreData把數(shù)據(jù)用面向?qū)ο蠓绞竭M(jìn)行管理,操作數(shù)據(jù)庫更方便芋浮。
CoreData的核心是Core Data stack(技術(shù)棧堆)。CoreData就是依靠Core Data stack中的幾個(gè)對(duì)象進(jìn)行數(shù)據(jù)操作的壳快。這幾對(duì)象是:
NSManagedObjectContext 纸巷,管理對(duì)象的上下文: 負(fù)責(zé)管理模型對(duì)象的一個(gè)集合,
NSManagedObjectModel 被管理的對(duì)象模型
NSPersistentStoreCoordinator 存儲(chǔ)調(diào)度器: 負(fù)責(zé)將數(shù)據(jù)保存到磁盤眶痰,
NSPersistentStore用于保存模型數(shù)據(jù)瘤旨,受NSPersistentStoreCoordinator 存儲(chǔ)調(diào)度器的操控。
這三個(gè)對(duì)象的關(guān)系如下面圖片所示竖伯,蘋果官方給出了這幾個(gè)對(duì)向關(guān)系的圖解存哲。簡單理解起來就是最上面的NSManagedObjectContext負(fù)責(zé)管理對(duì)象模型。然后將管理的對(duì)象模型發(fā)送給NSPersistentStoreCoordinator 存儲(chǔ)調(diào)度器七婴,存儲(chǔ)調(diào)度器通過NSPersistentStore操作SQLite語句祟偷,將數(shù)據(jù)持久化到本地,保存到StoryFile中打厘。

image
image
image

數(shù)據(jù)庫的使用也很簡單修肠,我們只需要在創(chuàng)建項(xiàng)目文件的時(shí)候勾選使用coreData的選項(xiàng),系統(tǒng)就會(huì)幫我們創(chuàng)建一個(gè)包含CoreData的項(xiàng)目文件户盯。

image

然后在界面上就會(huì)出現(xiàn)下面的變化嵌施。我們點(diǎn)擊添加屬性按鈕饲化,就能在數(shù)據(jù)庫中給數(shù)據(jù)模型添加屬性。

image

添加完數(shù)據(jù)庫后我們進(jìn)行下面操作就能將數(shù)據(jù)模型轉(zhuǎn)為代碼文件吗伤。

image

做完上面操作之后我們就能對(duì)數(shù)據(jù)庫模型進(jìn)行操作了吃靠。

image

我們?cè)诓僮鲾?shù)據(jù),對(duì)數(shù)據(jù)進(jìn)行增刪改查的時(shí)候足淆,都需要用到Core Data stack這個(gè)工具。我們自己可以封裝一個(gè)Core Data stack夕冲,這樣更能加深我們對(duì)Core Data stack這個(gè)工具的理解裂逐。
下面是封裝一個(gè)工具類的代碼:
首先是該工具類的.h文件中的代碼

#import <Foundation/Foundation.h>

#import <CoreData/CoreData.h>

#define KXBCoreManagerInstance [HMCoreDataStackManager shareInstance]

@interface HMCoreDataStackManager : NSObject

///單例
+(HMCoreDataStackManager*)shareInstance;

///管理對(duì)象上下文
@property(strong,nonatomic)NSManagedObjectContext *managerContenxt;

///模型對(duì)象
@property(strong,nonatomic)NSManagedObjectModel *managerModel;

///存儲(chǔ)調(diào)度器
@property(strong,nonatomic)NSPersistentStoreCoordinator *maagerDinator;

//保存數(shù)據(jù)的方法
-(void)save;

@end

然后是.m文件中的代碼

#import "HMCoreDataStackManager.h"

@implementation HMCoreDataStackManager

///單例的實(shí)現(xiàn)
+(HMCoreDataStackManager*)shareInstance
{
  static HMCoreDataStackManager *instance = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    instance = [[HMCoreDataStackManager alloc]init];
  });

  return instance;
}

-(NSURL*)getDocumentUrlPath
{
 ///獲取文件位置
 return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]
  ;
}

//懶加載managerContenxt
-(NSManagedObjectContext *)managerContenxt
{
  if (_managerContenxt != nil) {

    return _managerContenxt;
  }

  _managerContenxt = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];

  ///設(shè)置存儲(chǔ)調(diào)度器
  [_managerContenxt setPersistentStoreCoordinator:self.maagerDinator];

  return _managerContenxt;
}

///懶加載模型對(duì)象
-(NSManagedObjectModel *)managerModel
{

  if (_managerModel != nil) {

    return _managerModel;
  }

  _managerModel = [NSManagedObjectModel mergedModelFromBundles:nil];

  return _managerModel;
}

-(NSPersistentStoreCoordinator *)maagerDinator
{
  if (_maagerDinator != nil) {

    return _maagerDinator;
  }

  _maagerDinator = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:self.managerModel];

  //添加存儲(chǔ)器
  /**
  * type:一般使用數(shù)據(jù)庫存儲(chǔ)方式NSSQLiteStoreType
  * configuration:配置信息 一般無需配置
  * URL:要保存的文件路徑
  * options:參數(shù)信息 一般無需設(shè)置
  */

  //拼接url路徑
  NSURL *url = [[self getDocumentUrlPath]URLByAppendingPathComponent:@"sqlit.db" isDirectory:YES];

  [_maagerDinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:nil];

  return _maagerDinator;
}

-(void)save
{  ///保存數(shù)據(jù)
  [self.managerContenxt save:nil];
}

通過上面代碼可以看出封裝一個(gè)Core Data stack類并不是很難歹鱼,我們需要做的是創(chuàng)建一個(gè)單例,然后懶加載一個(gè)NSManagedObjectContext卜高,并給NSManagedObjectContext添加存儲(chǔ)調(diào)度器NSPersistentStoreCoordinator弥姻。
懶加載存儲(chǔ)調(diào)度器的時(shí)候給存儲(chǔ)調(diào)度器添加存儲(chǔ)器PersistentStore。在最后提供一個(gè)保存數(shù)據(jù)的方法掺涛,每次我們修改數(shù)據(jù)庫中文件數(shù)據(jù)的時(shí)候庭敦,都需要用Core Data stack調(diào)用save方法保存數(shù)據(jù)。
CoreData關(guān)于數(shù)據(jù)的操作無非就是增刪改查薪缆。增刪改查我們同樣需要使用自定義的Core Data stack工具類秧廉。
增加數(shù)據(jù):

Person *p = [NSEntityDescription insertNewObjectForEntityForName:@"Person" in Managed ObjectContext : kManagedObjectContext.managedObjectContext];
 p.age = @(13);
 p.name = @"張三"; 
[kManagedObjectContext save];

刪除數(shù)據(jù):

//1.創(chuàng)建一個(gè)查詢請(qǐng)求
 NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Person"]; 
//2.創(chuàng)建查詢謂詞(查詢條件) 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@",@"張三"];
 //3.給查詢請(qǐng)求設(shè)置謂詞
 request.predicate = predicate; 
//4.查詢數(shù)據(jù)
 NSArray<Person*> *arr = [kManagedObjectContext.managedObjectContext executeFetchRequest:request error:nil]; 
//5.刪除數(shù)據(jù)
 [kManagedObjectContext.managedObjectContext deleteObject:arr.firstObject]; 
//6.同步到數(shù)據(jù)庫 [kManagedObjectContext save];

修改數(shù)據(jù):

//1.創(chuàng)建一個(gè)查詢請(qǐng)求 
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Person"]; 
//2.創(chuàng)建查詢謂詞(查詢條件) 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@",@"張三"];
 //3.給查詢請(qǐng)求設(shè)置謂詞
 request.predicate = predicate;
 //4.查詢數(shù)據(jù) 
NSArray<Person*> *arr = [kManagedObjectContext.managedObjectContext executeFetchRequest:request error:nil]; 
//5.改變數(shù)據(jù)
 arr.firstObject.name = @"李四";
 arr.firstObject.age = @(18);
 //6.同步到數(shù)據(jù)庫
 [kManagedObjectContext save];

查詢數(shù)據(jù):

//1.創(chuàng)建一個(gè)查詢請(qǐng)求 
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Person"];
 //2.創(chuàng)建查詢謂詞(查詢條件) 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@",@"張三"]; 
//3.給查詢請(qǐng)求設(shè)置謂詞 
request.predicate = predicate; 
//4.查詢數(shù)據(jù) 
NSArray<Person*> *arr = [kManagedObjectContext.managedObjectContext executeFetchRequest:request error:nil]; NSLog(@"%@====%@",arr.firstObject.name,arr.firstObject.age);

使用CoreData我們可以輕松實(shí)現(xiàn)很多數(shù)據(jù)的操作拣帽,例如通訊錄數(shù)據(jù)錄的增刪改查减拭。
在這里提供一個(gè)通訊錄數(shù)據(jù)操作的demo蔽豺,使用CoreData拧粪,我們能輕松地實(shí)現(xiàn)通訊錄功能修陡。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市可霎,隨后出現(xiàn)的幾起案子魄鸦,更是在濱河造成了極大的恐慌号杏,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件庭惜,死亡現(xiàn)場離奇詭異,居然都是意外死亡节吮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門狸臣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事呜师∪㈣耄” “怎么了贾节?”我有些...
    開封第一講書人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長衷畦。 經(jīng)常有香客問我栗涂,道長,這世上最難降的妖魔是什么祈争? 我笑而不...
    開封第一講書人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任斤程,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘忿墅。我一直安慰自己扁藕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開白布疚脐。 她就那樣靜靜地躺著亿柑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪棍弄。 梳的紋絲不亂的頭發(fā)上望薄,一...
    開封第一講書人閱讀 51,775評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音呼畸,去河邊找鬼痕支。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蛮原,可吹牛的內(nèi)容都是我干的卧须。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼瞬痘,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼故慈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起框全,我...
    開封第一講書人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤察绷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后津辩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拆撼,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年喘沿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了闸度。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蚜印,死狀恐怖莺禁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情窄赋,我是刑警寧澤哟冬,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站忆绰,受9級(jí)特大地震影響浩峡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜错敢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一翰灾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦纸淮、人聲如沸平斩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽双戳。三九已至,卻和暖如春糜芳,著一層夾襖步出監(jiān)牢的瞬間飒货,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來泰國打工峭竣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留塘辅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓皆撩,卻偏偏與公主長得像扣墩,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子扛吞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356

推薦閱讀更多精彩內(nèi)容