Core Data 使用小封裝 - GFCoreDataSource

閱讀此文時廊移,假設(shè)你已經(jīng)對Core Data 有了一定的認識,熟知Core Data 框架下的幾個類及基本的使用方法,對多線程操作也有一定的了解。怎么禁漓?你是剛剛接觸Core Data的跟衅?也不要急著走,來都來了,隨便看看吧谒撼,也沒有多少文字食寡。

概念##

關(guān)于Core Data 的介紹、各種使用說明cookbook 非常多廓潜,在簡書站內(nèi)搜一下抵皱,就能發(fā)現(xiàn)好幾篇非常詳盡的善榛、圖文并茂的文章,所以這一塊兒我就略過了呻畸。

坑##

使用過Core Data 的兄弟們移盆,或多或少會說,Core Data 不同于其它系統(tǒng)框架:難入門伤为、難提高咒循、蹦潰多,等等绞愚。網(wǎng)上大量的手冊叙甸、幫助,但都是基本概念位衩,只教你邁出第一步裆蒸,但你想歡快地??起來,往往還需要自己琢磨糖驴,你看僚祷,我就琢磨出一條土路,用著還挺順手遂赠,現(xiàn)將其封裝久妆,分享出來給各位,請不吝指教跷睦。

GFCoreDataSource##

install:

pod 'GFCoreDataSource'

or source: github (內(nèi)附demo)
源碼目錄結(jié)構(gòu):

GFCoreDataSource
  |- GFCoreDataSource.h
  |- GFDataSource.h
  |- GFDataSource.m
  |- GFObjectOperation.h
  |- GFObjectOperation.m

如何使用筷弦?##

GFCoreDataSource 從名字也能看出來,這就是個數(shù)據(jù)源管理器抑诸,不錯烂琴,這個Data source 封裝了Core Data 對數(shù)據(jù)庫的查詢、寫入操作蜕乡,查詢操作在主線程奸绷,寫入操作在子線程,合并在主線程层玲,如果你的項目需要長時間處理大量的數(shù)據(jù)(超過萬條)号醉,那可能需要在子線程合并,我?guī)筒涣四阈量椋蛘吲吓桑ㄗh你采用性能表現(xiàn)更佳的 realm

定義自己的Data Source###

先聲明一個基于GFDataSource的data source

@interface MyDataSource : GFDataSource

@end

實例化

@implementation MyDataSource

+ (instancetype)sharedClient {
    static dispatch_once_t onceToken;
    static MyDataSource *client = nil;
    dispatch_once(&onceToken, ^{
        client = [[MyDataSource alloc] init];
    });
    
    return client;
}

- (instancetype)init {
    if (self = [super initWithManagedObjectContext:managedObjectContext
                                       coordinator:persistentStoreCoordinator
                                             class:[MyObjectOperation class]]) {
    }
    
    return self;
}
@end

此Data source一個實例可以實現(xiàn)對同一個SQLite數(shù)據(jù)庫的多種查詢與修改監(jiān)聽润绵,所以线椰,一般只需要創(chuàng)建一個實例,建議用+ (instancetype)sharedClient;方法來創(chuàng)建尘盼,其初始化時憨愉,需要傳入的三個參數(shù):

  1. managedObjectContext:NSManagedObjectContext 的實例烦绳,由主線程創(chuàng)建,查詢操作使用(因此配紫,查詢操作只能在主線程中使用)
  2. persistentStoreCoordinator:NSPersistentStoreCoordinator 的實例径密,子線程創(chuàng)建NSManagedObjectContext 實例時需要用到
  3. [MyObjectOperation class]:此處注冊了原子操作時對應(yīng)的類,此類中實現(xiàn)了具體的增笨蚁、刪睹晒、改操作趟庄,其聲明如下:
@interface MyObjectOperation : GFObjectOperation

@end

你需要實現(xiàn)相應(yīng)的方法:

@implementation MyObjectOperation

- (void)onAddObject:(id)object {
}

- (void)onEditObject:(NSManagedObject *)object edit:(NSDictionary *)edit {
}

- (void)onDeleteObject:(NSManagedObject *)object {
}

@end

注冊查詢括细、監(jiān)聽###

self.dataKey = @"viewListing";
self.dataSource = [MyDataSource sharedClient];

[self.dataSource registerDelegate:self
                           entity:[MyEntity entityName]
                        predicate:predicate
                  sortDescriptors:@[dateDescriptor]
               sectionNameKeyPath:nil
                              key:self.dataKey];

當(dāng)前的self需要實現(xiàn)GFDataSourceDelegate 協(xié)議,當(dāng)數(shù)據(jù)庫中滿足查詢條件的數(shù)據(jù)有變動時戚啥,self 會收到協(xié)議方法調(diào)用奋单,你如果是在UITableViewController 中注冊了監(jiān)聽,則需要添加如下代碼:


#pragma mark - GFDataSourceDelegate

- (void)dataSource:(id<GFDataSource>)dataSource willChangeContentForKey:(NSString *)key {
    [self.tableView beginUpdates];
}

- (void)dataSource:(id<GFDataSource>)dataSource didChangeContentForKey:(NSString *)key {
    [self.tableView endUpdates];
}

- (void)dataSource:(id<GFDataSource>)dataSource
  didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex
     forChangeType:(NSFetchedResultsChangeType)type
            forKey:(nullable NSString *)key {
    switch (type) {
        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationNone];
            break;
        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationNone];
            break;
            
        default:
            break;
    }
}

- (void)dataSource:(id<GFDataSource>)dataSource
   didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath
     forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
            forKey:(nullable NSString *)key {
    switch (type) {
        case NSFetchedResultsChangeUpdate:
            [self configureCell:[self.tableView cellForRowAtIndexPath:indexPath] atIndexPath:newIndexPath];
            break;
        case NSFetchedResultsChangeMove:
            [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
            [self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationNone];
            break;
        case NSFetchedResultsChangeInsert:
            [self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationNone];
            break;
        case NSFetchedResultsChangeDelete:
            [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
            break;
    }
}

本Data source 支持多個查詢條件猫十,只需要用不同的data key來區(qū)分览濒,比如在示例demo中有如下查詢:

self.dataSource = [DataSource sharedClient];
self.boxDataKey = @"boxData";
self.itemDataKey = @"itemData";

NSSortDescriptor *dateDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO];
[self.dataSource registerDelegate:self
                           entity:[BoxEntity entityName]
                        predicate:nil
                  sortDescriptors:@[dateDescriptor]
               sectionNameKeyPath:nil
                              key:self.boxDataKey];

[self.dataSource registerDelegate:self
                           entity:[ItemEntity entityName]
                        predicate:nil
                  sortDescriptors:@[dateDescriptor]
               sectionNameKeyPath:nil
                              key:self.itemDataKey];

數(shù)據(jù)增、刪拖云、改###

因數(shù)據(jù)的修改與界面無關(guān)贷笛,也與線程無關(guān),所以任何地方如果需要增宙项、刪乏苦、改數(shù)據(jù),直接用[MyDataSource sharedClient] 來操作便可尤筐,比如:

[[MyDataSource sharedClient] addObject:data];

修改和刪除都類似汇荐,可以看demo中具體實現(xiàn)。

最后##

本地數(shù)據(jù)庫存儲數(shù)據(jù)盆繁,已經(jīng)是app 不可或缺的一部分掀淘,我們只需要考慮選用哪一種方案,Core Data 雖然槽點太多油昂,但它是Apple 自家產(chǎn)品革娄,有其天然優(yōu)勢,還能與iCloud 無縫對接冕碟,如果你的項目沒有處理大量數(shù)據(jù)的需求拦惋,還是建議用Core Data,當(dāng)然鸣哀,新起之秀 realm 也是個不錯的選項架忌。
祝好!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末我衬,一起剝皮案震驚了整個濱河市叹放,隨后出現(xiàn)的幾起案子饰恕,更是在濱河造成了極大的恐慌,老刑警劉巖井仰,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件埋嵌,死亡現(xiàn)場離奇詭異,居然都是意外死亡俱恶,警方通過查閱死者的電腦和手機雹嗦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來合是,“玉大人了罪,你說我怎么就攤上這事〈先” “怎么了泊藕?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長难礼。 經(jīng)常有香客問我娃圆,道長,這世上最難降的妖魔是什么蛾茉? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任讼呢,我火速辦了婚禮阱驾,結(jié)果婚禮上箫老,老公的妹妹穿的比我還像新娘。我一直安慰自己威蕉,他們只是感情好吧寺,可當(dāng)我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布窜管。 她就那樣靜靜地躺著,像睡著了一般稚机。 火紅的嫁衣襯著肌膚如雪幕帆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天赖条,我揣著相機與錄音失乾,去河邊找鬼。 笑死纬乍,一個胖子當(dāng)著我的面吹牛碱茁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播仿贬,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼纽竣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蜓氨,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤聋袋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后穴吹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體幽勒,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年港令,在試婚紗的時候發(fā)現(xiàn)自己被綠了啥容。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡顷霹,死狀恐怖咪惠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情泼返,我是刑警寧澤硝逢,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站绅喉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏叫乌。R本人自食惡果不足惜柴罐,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望憨奸。 院中可真熱鬧革屠,春花似錦、人聲如沸排宰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽板甘。三九已至党瓮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間盐类,已是汗流浹背寞奸。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留在跳,地道東北人枪萄。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像猫妙,于是被迫代替她去往敵國和親瓷翻。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,969評論 2 355

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)齐帚,斷路器元践,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,152評論 25 707
  • 適讀對象: 需要入門Core Data的朋友; 像我一樣童谒,尚未學(xué)過數(shù)據(jù)庫相關(guān)課程单旁,不太懂怎么寫SQLite語句的朋...
    AntonyWong閱讀 5,205評論 8 21
  • 前幾天象浑,拆掉了左手腕上的手術(shù)縫合線,現(xiàn)在還有很明顯的疤痕琅豆,希望過段時間可以去除掉愉豺。 本來想說這是我人生第一次做手術(shù)...
    _淺墨_閱讀 553評論 2 2