Core Data: Batch Operation

Core Data 在近兩代系統(tǒng) iOS 8 和9中得到了大幅強(qiáng)化肖粮,解決了以往性能和批量操作的痛點(diǎn)孤页,主要有以下幾個(gè)新特性:
1.Batch Refresh
2.Batch Update
3.Batch Deletion
4.Asynchronous Fetch
不過(guò),這幾個(gè)新功能的共同特點(diǎn)是:特么都沒(méi)文檔D蜃I⑹!

Core Data 復(fù)習(xí)小圖:

Core Data Stack

以往我們的更新凌净、刪除操作只有在NSManagedObjectContext執(zhí)行保存后才在 Persistent Store 里生效悲龟,然而這個(gè)過(guò)程長(zhǎng)久以來(lái)一直被開(kāi)發(fā)者們?cè)嵅。吮啊atch Update 以及 Batch Deletion 的改進(jìn)在于直接在 Persistent Store 里操作须教,從 WWDC 提供的對(duì)比來(lái)看,速度有了大幅的提升斩芭,更新20000條記錄的速度接近直接使用 SQL 命令轻腺。
NSPersistentStoreRequest 及其衍生類

從上面的類繼承關(guān)系可以看出,NSFetchRequest類和其他幾個(gè)類關(guān)系還是挺近的划乖,都是NSPersistentStoreRequest的子類贬养,使用起來(lái)還是很方便的,只是需要使用新的 API琴庵。

NSManagedObjectContext.executeRequest:error

批量刷新 Batch Refresh

context.refreshAllObjects()

這個(gè)功能姍姍來(lái)遲误算,直到今天的 iOS 9 才到來(lái),在以往要刷新 NSManagedObjectContext 里的所有對(duì)象是很不方便的迷殿,特別是 iOS 8 里添加了 Batch Update 后儿礼,這個(gè)功能簡(jiǎn)直是迫在眉睫了。這個(gè)功能的作用就是我們想象的那樣:
1.刷新在 context 里注冊(cè)的所有對(duì)象的數(shù)據(jù)庆寺,與 Persistent Store 同步;
2.沒(méi)有發(fā)生變化的對(duì)象將會(huì)進(jìn)入 faults 狀態(tài)蚊夫,降低內(nèi)存占用;
3.保留尚未保存的變化懦尝;
4.關(guān)系引用保持有效知纷。

批量更新 Batch Update

BigNerdRanch 出品的使用指南:New in Core Data and iOS 8: Batch Updating壤圃。

批量更新在速度方面有很大提升,內(nèi)存占用也比傳統(tǒng)方案少很多屈扎。示例代碼將所有未讀的郵件標(biāo)記為已讀埃唯,直接在 Persistetn Store 層面操作,性能非常好鹰晨。副作用是:1.更新后不會(huì)主動(dòng)刷新 context;2.更新不會(huì)運(yùn)行有效性驗(yàn)證止毕;3.自己處理沖突模蜡。

let batchUpdateRequest = NSBatchUpdateRequest.init(entityName: "Mail")
batchUpdateRequest.predicate = NSPredicate(format: "read == %@", false)
//propertiesToUpdate 使用 property 為 key,任何 NSExpression 作為值扁凛,這點(diǎn)非常強(qiáng)大忍疾。
batchUpdateRequest.propertiesToUpdate = ["read": true]
batchUpdateRequest.resultType = .UpdatedObjectIDsResultType

context.performBlock(){
    do{
        let batchUpdateResult = try context.executeRequest(batchUpdateRequest) as! NSBatchUpdateResult
        if #available(iOS 9, *){
           context.refreshAllObjects()
        }else{
            let updatedIDs = batchUpdateResult.result as! [NSManagedObjectID]
            for objectID in updatedIDs{
                if let updatedObject = context.objectRegisteredForID(objectID){
                    context.refreshObject(updatedObject, mergeChanges: true)
                }
            }
        }
    } catch {
            //Error Handle
    }
}

NSBatchUpdateRequest需要配置的屬性如下:
1.entityName: 指定 entity,用作初始化
2.predicate:用于篩選
3.propertiesToUpdate:更新的鍵值對(duì)
4.resultType:有三種類型谨朝,指定返回值類型卤妒。
NSStatusOnlyResultType:默認(rèn)值,表示操作狀態(tài)字币,成功或失敗
NSUpdatedObjectsCountResultType:返回被更新的數(shù)量
NSUpdatedObjectIDsResultType:返回含有更新對(duì)象的 ObjectID 的數(shù)組

批量刪除 Batch Deletion

批量刪除與上面的批量更新非常類似则披,也是直接在 Persistent Store 里操作。有兩種初始化方式洗出,一種是對(duì)NSFetchRequest的封裝士复,另一種是指定要?jiǎng)h除對(duì)象的 ObjectID。示例代碼刪除所有垃圾郵件:

if #available(iOS 9.0, *) {
    //init with FetchRequest
    let fetchRequest = NSFetchRequest.init(entityName: "Mail")
    fetchRequest.predicate = NSPredicate(format: "isSpam == %@", true)
    let batchDeleteRequest = NSBatchDeleteRequest.init(fetchRequest: fetchRequest)
        
    //Or init with ObjectIDs
    let deleteIDs: [NSManagedObjectID] = ...
    let batchDeleteRequest = NSBatchDeleteRequest.init(objectIDs: deleteIDs)
        
    context.performBlock(){
        do{
            try context.executeRequest(batchDeleteRequest)
            context.refreshAllObjects()
        }catch{
           //Error Handle
        }
    }       
}else{
    // Fallback on earlier versions
    Sample from stack-overflow:(http://stackoverflow.com/questions/1383598/core-data-quickest-way-to-delete-all-instances-of-an-entity/1383645#1383645)
}

NSBatchDeleteRequest的 resultType 有三種值:
1.NSBatchDeleteResultTypeStatusOnly:默認(rèn)值翩活,不返回任何值
2.NSBatchDeleteResultTypeObjectIDs:返回含有被刪除對(duì)象 ObjectID 的數(shù)組
3.NSBatchDeleteResultTypeCount:返回被刪除的數(shù)量
批量刪除的副作用和批量更新很類似:1.刪除后不更新 context阱洪,不會(huì)發(fā)出通知,因此需要手動(dòng)刷新菠镇;2.不會(huì)運(yùn)行有效性驗(yàn)證(主要是一些關(guān)系的約束)冗荸。

異步獲取 Asynchronous Fetch

BigNerdRanch 出品的使用指南: New in Core Data and iOS 8: Asynchronous Fetching。這個(gè)特性不能算作批量操作的內(nèi)容利耍,但作為一個(gè)有用的特性蚌本,還是記錄下。

Managed Object Context 的 fetch 是同步操作堂竟,雖然我們可以使用多 context 來(lái)解決阻塞主線程的問(wèn)題魂毁,但 fetch 時(shí)依然會(huì)阻塞后臺(tái)進(jìn)程,相對(duì)而言出嘹,異步獲取就解決了這個(gè)問(wèn)題席楚。NSAsynchronousFetchRequest類在 iOS 8 中推出,但是無(wú)論是文檔還是在 SDK 里的頭文件里都找不到税稼,同級(jí)別的類至少還能在 SDK 的頭文件里找到烦秩,不知為何垮斯。

NSAsynchronousFetchRequest依然是對(duì)NSFetchRequest的封裝,由于是異步的只祠,所以搭配了 completionBlock 用于 fetch 完成時(shí)執(zhí)行特定操作兜蠕。基于異步的定位抛寝,Asynchronous Fetch 還配置了顯示 fetch 進(jìn)度和取消 fetch 的功能熊杨。但是,但是盗舰,所有的中間類都找不到文檔和相關(guān)信息晶府,可以說(shuō)這個(gè)特性相當(dāng)?shù)牟挥押茫绻皇翘貏e需要異步特性钻趋,還是別用了吧川陆。

異步請(qǐng)求用法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蛮位,隨后出現(xiàn)的幾起案子较沪,更是在濱河造成了極大的恐慌,老刑警劉巖失仁,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尸曼,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡陶因,警方通過(guò)查閱死者的電腦和手機(jī)骡苞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)楷扬,“玉大人解幽,你說(shuō)我怎么就攤上這事『嫫唬” “怎么了躲株?”我有些...
    開(kāi)封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)镣衡。 經(jīng)常有香客問(wèn)我霜定,道長(zhǎng),這世上最難降的妖魔是什么廊鸥? 我笑而不...
    開(kāi)封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任望浩,我火速辦了婚禮,結(jié)果婚禮上惰说,老公的妹妹穿的比我還像新娘磨德。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布典挑。 她就那樣靜靜地躺著酥宴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪您觉。 梳的紋絲不亂的頭發(fā)上拙寡,一...
    開(kāi)封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天琳水,我揣著相機(jī)與錄音肆糕,去河邊找鬼在孝。 笑死,一個(gè)胖子當(dāng)著我的面吹牛浑玛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播顾彰,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼胃碾!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起仆百,我...
    開(kāi)封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎俄周,沒(méi)想到半個(gè)月后吁讨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體峦朗,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡建丧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了波势。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片翎朱。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖尺铣,靈堂內(nèi)的尸體忽然破棺而出拴曲,到底是詐尸還是另有隱情,我是刑警寧澤凛忿,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布澈灼,位于F島的核電站,受9級(jí)特大地震影響侄非,放射性物質(zhì)發(fā)生泄漏蕉汪。R本人自食惡果不足惜流译,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望者疤。 院中可真熱鬧福澡,春花似錦、人聲如沸驹马。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)糯累。三九已至算利,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泳姐,已是汗流浹背效拭。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留胖秒,地道東北人缎患。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像阎肝,于是被迫代替她去往敵國(guó)和親挤渔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

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