4.2 Faulting和Uniquing (Core Data Programming Guide翻譯)

這是蘋(píng)果官方文檔 Core Data Programming Guide 的渣翻譯。

Faulting可以降低通過(guò)在持久化存儲(chǔ)中保留占位對(duì)象(faults)的方式來(lái)降低應(yīng)用內(nèi)存的使用。有一個(gè)叫uniquing的相關(guān)特性能確保上述功能,在一個(gè)既定的托管對(duì)象上下文中抬闯,一條既定記錄只會(huì)有一個(gè)托管對(duì)象。

Faulting限制了對(duì)象圖的大小

托管對(duì)象代表了持久化存儲(chǔ)中的數(shù)據(jù)关筒。在某些情況下托管對(duì)象可能是一個(gè)fault —— 一個(gè)還沒(méi)有從外部數(shù)據(jù)存儲(chǔ)中加載到屬性值的對(duì)象溶握。Fualting降低了應(yīng)用的內(nèi)存消耗。一個(gè)fault是一個(gè)表示了一個(gè)尚未完全實(shí)現(xiàn)的托管對(duì)象蒸播,或是一個(gè)表示了一個(gè)關(guān)系的集合對(duì)象睡榆。

  • 一個(gè)托管對(duì)象fault是一個(gè)相應(yīng)類(lèi)的實(shí)例,但是它的持久化變量還沒(méi)初始化袍榆。
  • 一個(gè)關(guān)系fault是表示了這個(gè)關(guān)系的集合類(lèi)的子類(lèi)胀屿。

Faulting允許Core Data在對(duì)象圖上放置邊界。因?yàn)橐粋€(gè)fault是沒(méi)有被實(shí)現(xiàn)的包雀,一個(gè)托管對(duì)象fault消耗更少的內(nèi)存宿崭,并且關(guān)聯(lián)到一個(gè)fault的托管對(duì)象完全不需要表示在內(nèi)存中。

為了說(shuō)明這一點(diǎn)馏艾,可以想象一個(gè)應(yīng)用允許一個(gè)用戶去查詢并編輯一個(gè)“雇員”的詳情劳曹。這個(gè)“雇員”有一個(gè)關(guān)系是指向一個(gè)“經(jīng)理”和一個(gè)關(guān)系指向一個(gè)“部門(mén)”,并且這些對(duì)象反過(guò)來(lái)也有其他關(guān)系琅摩。如果你在持久化存儲(chǔ)中僅僅查詢一個(gè)“雇員”,它的“經(jīng)理”锭硼、“部門(mén)”和“報(bào)告”關(guān)系都是用faults初始化表示的房资。圖13-1展示了使用fault來(lái)表示的“部門(mén)”關(guān)系。

圖13-1 一個(gè)使用fault表示的“部門(mén)”


IMG
IMG

雖然這個(gè)fault是一個(gè)“部門(mén)”類(lèi)的實(shí)例檀头,但是它并沒(méi)有被實(shí)現(xiàn) —— 任何一個(gè)它的持久化實(shí)例變量都還沒(méi)被設(shè)定轰异。這就意味著不單單“部門(mén)”對(duì)象消耗更好的內(nèi)存岖沛,并且不需要填充它的“雇員”關(guān)系。如果需要讓對(duì)象圖變得完整搭独,那就編輯一個(gè)“雇員”的一個(gè)屬性婴削,它最后就會(huì)去創(chuàng)建對(duì)象來(lái)表示整個(gè)結(jié)構(gòu)。

Firing Faults

Fault處理是直接的 —— 你不需要執(zhí)行任何查詢來(lái)實(shí)現(xiàn)一個(gè)fault牙肝。如果在某些場(chǎng)合一個(gè)fault對(duì)象的持久化屬性被訪問(wèn)到了唉俗,那么Core Data就會(huì)自動(dòng)查詢數(shù)據(jù)來(lái)初始化對(duì)象。這個(gè)過(guò)程一般被稱(chēng)為“fire the fault”配椭。如果你訪問(wèn)“部門(mén)”對(duì)象上的一個(gè)屬性虫溜,例如“名字”,那么這個(gè)fault就會(huì)被fire —— 并且在這種情況Core Data會(huì)為你執(zhí)行一個(gè)查詢來(lái)檢索到所有的對(duì)象屬性股缸。

Core Data在一個(gè)fault的一個(gè)持久化屬性(例如“名字”)被訪問(wèn)到的時(shí)候fire fault衡楞。然而,一個(gè)個(gè)地fire fault是十分低效的敦姻,并且有更好的策略來(lái)從持久化存儲(chǔ)中拿到數(shù)據(jù)(參考Decreasing Fault Overhead)瘾境。想要更高效處理fault和關(guān)系,可以參考Fetching Managed ObjectsPreventing a Fault from Firing镰惦。

當(dāng)一個(gè)fault被fire寄雀,如果這個(gè)數(shù)據(jù)在緩存中可用Core Data不會(huì)再去存儲(chǔ)中獲取。使用緩存命中陨献,轉(zhuǎn)換一個(gè)fault為一個(gè)已實(shí)現(xiàn)的托管對(duì)象是非澈杏蹋快的 —— 就像普通的托管對(duì)象被實(shí)例化一樣。如果這個(gè)數(shù)據(jù)不在緩存中可用眨业,Core Data會(huì)自動(dòng)為這個(gè)fault執(zhí)行查詢急膀;這就能從持久化存儲(chǔ)中獲取數(shù)據(jù),并再次放進(jìn)內(nèi)存中龄捡。

一個(gè)對(duì)象是否是fault簡(jiǎn)單地意味著一個(gè)既定的托管對(duì)象是否擁有已被包裝好的持久化屬性和已經(jīng)準(zhǔn)備好被使用卓嫂。如果你需要判斷一個(gè)對(duì)象是否是fault,可以調(diào)用它的“isFault”方法聘殖,這個(gè)方法不會(huì)fire這個(gè)fault(沒(méi)有訪問(wèn)任何關(guān)系或?qū)傩裕┏况āH绻癷sFault”返回“NO”鳖谈,那么這個(gè)數(shù)據(jù)應(yīng)該存在內(nèi)存中并且不是fault帝际。然后,如果“isFault”返回“YES”跑芳,并不能簡(jiǎn)單認(rèn)為這個(gè)數(shù)據(jù)不在內(nèi)存中突照。這個(gè)數(shù)據(jù)可能存在內(nèi)存中帮非,或者不存在,取決于許多影響到緩存機(jī)制的因素。

雖然“description”方法不會(huì)引起fault被fire末盔,但是如果你實(shí)現(xiàn)了一個(gè)自定義的“decription”方法并訪問(wèn)了對(duì)象的持久化屬性筑舅,那么這個(gè)fault會(huì)被fire。強(qiáng)烈不建議你用此方式覆寫(xiě)“description”陨舱。

不可以根據(jù)需要只加載托管對(duì)象中的某些屬性翠拣,而不實(shí)現(xiàn)整個(gè)對(duì)象(查詢所有屬性值)。關(guān)于如何處理大數(shù)據(jù)屬性游盲,參考 Binary Large Data Objects (BLOBs)误墓。

轉(zhuǎn)換對(duì)象為Fault

轉(zhuǎn)換一個(gè)已實(shí)現(xiàn)的對(duì)象為fault對(duì)于整理對(duì)象圖來(lái)說(shuō)是十分有用的,也能確保屬性值是同步的背桐。轉(zhuǎn)換一個(gè)托管對(duì)象為fault釋放不必要的內(nèi)存优烧,并設(shè)置它的內(nèi)存屬性值為nil。(參考Reducing Memory Overhead并保證數(shù)據(jù)時(shí)最新的)链峭。

你可以使用"refreshObject:mergeChanges:"方法轉(zhuǎn)換一個(gè)已實(shí)現(xiàn)對(duì)象為fault畦娄。如果你傳遞"NO"作為“mergeChanges”參數(shù),你必須確保這個(gè)對(duì)象的關(guān)系沒(méi)有變更弊仪。否則熙卡,當(dāng)你保存了這個(gè)上下文的時(shí)候,你會(huì)引發(fā)持久化存儲(chǔ)的引用的完整性問(wèn)題励饵。

當(dāng)一個(gè)對(duì)象轉(zhuǎn)變成為了fault驳癌,它的"didTurnIntoFault"方法就會(huì)被調(diào)用。你可能實(shí)現(xiàn)了一個(gè)自定義“didTurnIntoFault”方法來(lái)實(shí)現(xiàn)一些清理工作功能役听。例如颓鲜,保證數(shù)據(jù)是最新的。

注意
Core Data避免使用屬于“unfaulting”因?yàn)樗哂忻曰笮缘溆琛2荒苷f(shuō)“unfaulting”一個(gè)虛擬內(nèi)存事件fault甜滨。
事件fault可以是被觸發(fā)、引發(fā)瘤袖、fire(激發(fā)衣摩?)或者碰到。
當(dāng)然捂敌,你可以通過(guò)不同的方法來(lái)釋放內(nèi)存艾扮。Core Data稱(chēng)之為轉(zhuǎn)換一個(gè)對(duì)象為fault。

Fault和KVO通知

當(dāng)Core Data轉(zhuǎn)換一個(gè)對(duì)象為fault占婉,key-value observing(KVO)變更通知就會(huì)發(fā)送到這個(gè)對(duì)象的屬性上泡嘴。如果你正在觀察一個(gè)被轉(zhuǎn)換成了fault的對(duì)象的屬性,并且這個(gè)fault突然被實(shí)現(xiàn)化了锐涯,你會(huì)收到其實(shí)值并沒(méi)有真正改變的屬性的變更通知磕诊。參考Key-Value Observing Programming Guide

雖然這些值從你的角度來(lái)看并沒(méi)有發(fā)生改變纹腌,但是在內(nèi)存中隨著對(duì)象的具現(xiàn)化霎终,其實(shí)每個(gè)字節(jié)都發(fā)生了改變。KVO機(jī)制要求無(wú)論在任何時(shí)候只要根據(jù)對(duì)比指針判斷值發(fā)生了改變升薯,Core Data都要發(fā)出通知莱褒。KVO需要這些通知來(lái)跟蹤跨key path和依賴(lài)對(duì)象的改變。

Uniquing確保一個(gè)托管對(duì)象對(duì)應(yīng)一個(gè)上下文中的一條記錄

Core Data確保涎劈,在一個(gè)托管對(duì)象上下文广凸,一個(gè)持久化存儲(chǔ)中的實(shí)體是和唯一一個(gè)托管對(duì)象關(guān)聯(lián)的。這個(gè)技術(shù)就是uniquing蛛枚。如果沒(méi)有uniquing谅海,你可能要無(wú)休止處理一個(gè)上下文中超過(guò)一個(gè)托管對(duì)象表示同一條記錄。

例如蹦浦,試想如圖13-2展示的情景扭吁;兩個(gè)“雇員”被加載到了一個(gè)托管對(duì)象上下文中。每個(gè)“雇員”都有一個(gè)"部門(mén)"關(guān)系盲镶,但是這時(shí)候“部門(mén)”是fault侥袜。

圖13-2 獨(dú)立的“部門(mén)”對(duì)象fault


IMG
IMG

這看起來(lái)就是每個(gè)“雇員”都有一個(gè)獨(dú)立的“部門(mén)”,并且如果你調(diào)用每個(gè)“雇員”的“部門(mén)” —— 轉(zhuǎn)換“部門(mén)”fault稱(chēng)為普通對(duì)象 —— 你就會(huì)得到兩個(gè)在內(nèi)存中獨(dú)立的“部門(mén)”溉贿。然而枫吧,如果兩個(gè)“雇員”都屬于同一個(gè)“部門(mén)”(例如,市場(chǎng)部)宇色,然后Core Data要確保在一個(gè)既定的托管對(duì)象上下文中只有一個(gè)對(duì)象表示“市場(chǎng)部”九杂。如果兩個(gè)“雇員”都屬于同一個(gè)部門(mén),他們的“部門(mén)”關(guān)系都應(yīng)該引用同一個(gè)fault宣蠕,就如圖13-3展示的那樣例隆。

圖13-3 表示兩個(gè)“雇員”共同工作的“部門(mén)”的唯一fault


IMG
IMG

如果沒(méi)有uniquing,當(dāng)你獲取每個(gè)“雇員”并且調(diào)用“部門(mén)”的時(shí)候 —— 從而要fire每個(gè)對(duì)應(yīng)的fault —— 一個(gè)新的“部門(mén)”對(duì)象每次都會(huì)被創(chuàng)建出來(lái)植影。這樣會(huì)導(dǎo)致出現(xiàn)很多對(duì)象裳擎,每個(gè)都表示同一個(gè)“部門(mén)”,可能會(huì)導(dǎo)致不同步的思币、沖突的數(shù)據(jù)鹿响。當(dāng)上下文保存的時(shí)候,就不能保證正確的數(shù)據(jù)能夠提交到存儲(chǔ)中谷饿。

更通俗地說(shuō)惶我,在一個(gè)既定的上下文中,所有表示“市場(chǎng)部”的托管對(duì)象都指向同一個(gè)實(shí)例 —— 他們擁有相同的“市場(chǎng)部”數(shù)據(jù)視圖 —— 即使這個(gè)“市場(chǎng)部”是個(gè)fault博投。

注意
這次討論主要是圍繞單個(gè)托管對(duì)象上下文的绸贡。每一個(gè)托管對(duì)象上下文都表示一個(gè)不同的數(shù)據(jù)視圖。
如果同一個(gè)“雇員”加載到了第二個(gè)上下文,那么他們 —— 并且對(duì)應(yīng)的所有“部門(mén)”對(duì)象 —— 都在對(duì)象中表現(xiàn)成不同的對(duì)象听怕。
在不同的上下文的中對(duì)象可能存在不同的捧挺、沖突的數(shù)據(jù)。這恰恰是Core Data架構(gòu)的任務(wù)尿瞭,同時(shí)去檢測(cè)闽烙、解決這些沖突。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末声搁,一起剝皮案震驚了整個(gè)濱河市黑竞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疏旨,老刑警劉巖很魂,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異檐涝,居然都是意外死亡遏匆,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)骤铃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)拉岁,“玉大人,你說(shuō)我怎么就攤上這事惰爬『芭” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵撕瞧,是天一觀的道長(zhǎng)陵叽。 經(jīng)常有香客問(wèn)我,道長(zhǎng)丛版,這世上最難降的妖魔是什么巩掺? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮页畦,結(jié)果婚禮上胖替,老公的妹妹穿的比我還像新娘。我一直安慰自己豫缨,他們只是感情好独令,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著好芭,像睡著了一般燃箭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上舍败,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天招狸,我揣著相機(jī)與錄音敬拓,去河邊找鬼。 笑死裙戏,一個(gè)胖子當(dāng)著我的面吹牛乘凸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挽懦,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼翰意,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼木人!你這毒婦竟也來(lái)了信柿?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤醒第,失蹤者是張志新(化名)和其女友劉穎渔嚷,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體稠曼,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡形病,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了霞幅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漠吻。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖司恳,靈堂內(nèi)的尸體忽然破棺而出途乃,到底是詐尸還是另有隱情,我是刑警寧澤扔傅,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布耍共,位于F島的核電站,受9級(jí)特大地震影響猎塞,放射性物質(zhì)發(fā)生泄漏试读。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一荠耽、第九天 我趴在偏房一處隱蔽的房頂上張望钩骇。 院中可真熱鬧,春花似錦铝量、人聲如沸倘屹。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)唐瀑。三九已至,卻和暖如春插爹,著一層夾襖步出監(jiān)牢的瞬間哄辣,已是汗流浹背请梢。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留力穗,地道東北人毅弧。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像当窗,于是被迫代替她去往敵國(guó)和親够坐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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