版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.09.14 |
前言
KVO
具有更強大的功能,是蘋果給我們的一個回調(diào)機制,在某個對象注冊監(jiān)聽者后怜庸,在被監(jiān)聽的對象發(fā)生改變時,對象會發(fā)送一個通知給監(jiān)聽者垢村,以便監(jiān)聽者執(zhí)行回調(diào)操作割疾。接下來幾篇就詳細的解析一下KVO。感興趣的可以看上面幾篇嘉栓。
1. KVO解析(一) —— 基本了解
2. KVO解析(二) —— 一個簡單的KVO實現(xiàn)
3. KVO解析(三) —— KVO合規(guī)性
Faulting and Uniquing
故障通過在持久存儲中保留占位符對象(故障)來減少應用程序的內(nèi)存使用宏榕。 一個名為uniquing
的相關功能可以確保在給定的托管對象上下文中,您不會有多個托管對象來表示給定的記錄侵佃。
faulting
和 uniquing
是理解CoreData
的兩個比較關鍵的概念麻昼。
-
faulting
是一種CoreData
降低內(nèi)存使用的機制,是惰性加載的一種馋辈。 -
Uniquing
是輔助faulting
的機制抚芦,它保證了在一個managed object context
中只有一個managed object
來表達一條記錄。
Faulting Limits the Size of the Object Graph - 故障限制對象圖的大小
管理對象通常表示持久存儲中保存的數(shù)據(jù)迈螟。 在某些情況下叉抡,被管理對象可能是一個故障 - 其屬性值尚未從外部數(shù)據(jù)存儲加載的對象。 故障可減少應用程序消耗的內(nèi)存量答毫。 故障是表示尚未完全實現(xiàn)的管理對象的占位符對象或表示關系的集合對象:
- 管理對象故障是適當類的實例褥民,但其持久變量尚未初始化。
- 關系故障是代表關系的集合類的子類洗搂。
故障允許Core Data
在對象圖上放置邊界消返。 由于沒有實現(xiàn)故障,管理對象故障消耗的內(nèi)存較少耘拇,與故障相關的管理對象根本不需要在內(nèi)存中進行表示撵颊。
為了說明,考慮允許用戶獲取和編輯有關單個員工的詳細信息的應用程序驼鞭。 員工與經(jīng)理和部門有關系秦驯,這些對象又有其他關系。 如果您從永久存儲中檢索一個Employee
對象挣棕,則其經(jīng)理,部門和報表關系最初由故障表示亲桥。 下圖顯示了以故障為代表的員工部門關系洛心。
雖然這個錯誤是Department
類的一個實例,但它還沒有被實現(xiàn) - 它的持久實例變量都沒有設置题篷。 這意味著词身,不僅部門對象本身消耗的內(nèi)存較少,也不需要填充其員工關系番枚。 如果要求對象圖完成法严,則要編輯單個員工的單個屬性损敷,最終將需要創(chuàng)建對象以表示整個公司結(jié)構(gòu)。
Firing Faults - 故障開啟
故障處理是透明的 - 您不必執(zhí)行抓取來實現(xiàn)故障深啤。 如果在某個階段訪問了故障對象的持久屬性拗馒,Core Data
將自動檢索對象的數(shù)據(jù)并初始化對象。 這個過程通常被稱為觸發(fā)故障溯街。 如果您訪問Department對象(例如诱桂,其名稱)上的屬性,則會發(fā)生故障觸發(fā)呈昔,Core Data將執(zhí)行擷取以檢索所有對象的所有屬性挥等。(有關觸發(fā)故障開啟可以參考NSManagedObject)。
當訪問故障的持久屬性(如firstName)時堤尾,Core Data
將自動觸發(fā)故障肝劲。 然而,單獨觸發(fā)故障可能是低效的郭宝,并且有更好的策略從永久存儲器獲取數(shù)據(jù)(請參閱 Decreasing Fault Overhead)涡相。 要有效地處理故障和關系,請參閱 Fetching Managed Objects和Preventing a Fault from Firing剩蟀。
當故障觸發(fā)時催蝗,如果數(shù)據(jù)在緩存中可用,則Core Data不會返回到存儲育特。 使用緩存命中丙号,將故障轉(zhuǎn)換為實現(xiàn)的管理對象非常快 - 它與被管對象的正常實例基本相同缰冤。 如果數(shù)據(jù)在緩存中不可用犬缨,則Core Data將自動執(zhí)行故障對象的提取; 這導致到持久存儲器的往返行程以獲取數(shù)據(jù),并且再次將數(shù)據(jù)高速緩存在存儲器中棉浸。
一個對象是否是一個故障怀薛,只是指一個給定的被管理對象是否具有所有的持久屬性,并且可以使用迷郑。 如果需要確定對象是否為故障枝恋,請調(diào)用其isFault方法而不觸發(fā)故障(不訪問任何關系或?qū)傩裕?如果isFault
返回NO
,則數(shù)據(jù)必須在內(nèi)存中嗡害,因此對象不是故障焚碌。 但是,如果isFault
返回YES
霸妹,則并不意味著數(shù)據(jù)不在內(nèi)存中十电。 數(shù)據(jù)可能在內(nèi)存中,或者可能不是,這取決于影響緩存的許多因素鹃骂。
雖然標準description方法不會導致故障觸發(fā)台盯,但如果實現(xiàn)訪問對象的持久屬性的自定義description
方法,則故障將觸發(fā)畏线。 你們絕對不鼓勵用這種方式重寫description
静盅。
無法根據(jù)需要加載托管對象的各個屬性,并避免實現(xiàn)(檢索整個對象的所有屬性值)象踊。 對于處理大型屬性的模式温亲,請參閱 Binary Large Data Objects (BLOBs)。
Turning Objects into Faults - 對象轉(zhuǎn)換為故障
將實現(xiàn)的對象轉(zhuǎn)換為故障在修剪對象圖中以及確保屬性值為最新時可能很有用杯矩。 將受管對象轉(zhuǎn)換為故障會釋放不必要的內(nèi)存栈虚,并將其內(nèi)存中的屬性值設置為nil。 (請參閱Reducing Memory Overhead并確保數(shù)據(jù)更新史隆。)
您可以使用 refreshObject:mergeChanges:方法將實現(xiàn)的對象轉(zhuǎn)換為故障魂务。 如果您將NO作為mergeChanges
參數(shù)傳遞,則必須確保該對象的關系沒有更改泌射。 如果有粘姜,然后保存上下文,您將引入持久存儲參照完整性問題熔酷。
當對象變成故障時孤紧,將調(diào)用其didTurnIntoFault方法。 您可以實施自定義的didTurnIntoFault
方法來執(zhí)行各種管理功能拒秘。
還需要注意的是:Core Data避免了這個unfaulting
術(shù)語号显,因為它是混亂的。 虛擬內(nèi)存頁錯誤沒有unfaulting
躺酒。 頁面錯誤被觸發(fā)押蚤,引起,開啟或遇到羹应。 當然揽碘,您可以通過各種方式將內(nèi)存釋放回內(nèi)核(使用函數(shù)vm_deallocate
,munmap
或sbrk
)园匹。 Core Data將其描述為“turning an object into a fault
”雳刺。
Faults and KVO Notifications - 故障和KVO通知
當Core Data將對象變成故障時,鍵值觀察(KVO)更改通知將發(fā)送到對象的屬性偎肃。 如果您正在觀察變成故障的對象的屬性煞烫,并且隨后實現(xiàn)了故障,你接收的更改通知的屬性值實際上并沒有實際上的改變累颂。
雖然這些值從您的角度來看不會從語義上改變,但是隨著對象的實現(xiàn),內(nèi)存中的字面字節(jié)也在改變紊馏。 鍵值觀察機制要求Core Data在根據(jù)指針比較的角度改變值時發(fā)出通知料饥。 KVO需要這些通知來跟蹤關鍵路徑和依賴對象的變化。
Uniquing Ensures a Single Managed Object per Record per Context - Uniquing確定每個上下文記錄的單個管理對象
Core Data可確保在給定的托管對象上下文中 - persistent store
中的條目僅與一個管理對象相關聯(lián)朱监。 該技術(shù)被稱為uniquing
岸啡。 沒有uniquing
,你可能會得到一個上下文來維護多個對象來表示給定的記錄赫编。
例如巡蘸,考慮下圖所示的情況,兩名員工已被提取到一個單一managed object context.
中擂送。 每個人都與一個部門有關系悦荒,但該部門目前由一個故障表示。
看來每個員工都有一個單獨的部門嘹吨,如果您為每個員工調(diào)用部門 - 將部門故障轉(zhuǎn)換為常規(guī)對象搬味,則內(nèi)存中將有兩個單獨的部門對象。 但是蟀拷,如果兩個員工都屬于同一部門(例如Marketing)碰纬,則Core Data可確保(在給定的托管對象上下文中)僅創(chuàng)建了一個代表市場部門的對象。 如果兩個員工都屬于同一個部門问芬,則他們的部門關系因此都會引用相同的故障悦析,如下圖所示。
沒有uniquing
此衅,如果您獲取所有員工强戴,并在每個部門中調(diào)用部門,從而觸發(fā)相應的故障 - 每次都會創(chuàng)建一個新的部門對象炕柔。 這將導致一些對象酌泰,每個對象代表同一個部門,可能包含不同和沖突的數(shù)據(jù)匕累。 當保存上下文時陵刹,將無法確定正確的數(shù)據(jù)以提交存儲。
更廣泛地說欢嘿,在給定上下文中衰琐,引用市場部門對象的所有托管對象都引用了相同的實例,即它們具有市場營銷部門數(shù)據(jù)的單一視圖炼蹦,即使市場部門對象是故障的羡宙。
這個討論集中在單一的管理對象上下文中。 每個受管對象上下文都表示數(shù)據(jù)的不同視圖掐隐。 如果相同的員工被提取到第二個上下文中狗热,那么它們和相應的Department對象都由內(nèi)存中的不同對象表示钞馁。 不同上下文中的對象可能具有不同的和沖突的數(shù)據(jù)。 Core Data架構(gòu)正是檢測和解決這些沖突的很好的角色匿刮。
后記
這里很大一部分是關于Core Data的僧凰,只有一個小點與KVO相關,但是蘋果文檔寫在一起熟丸,我就都發(fā)出來了训措,大家感興趣的也可以看看Core Data方面的知識。未完光羞,待續(xù)~~~