iOS CoreData詳解(四)Faulting and Uniquing

來源:互聯網
上載者:User

標籤:ios   coredata   faulting   uniquing   

原創blog,轉載請註明出處
blog.csdn.net/hello_hwc
歡迎關注我的iOS SDK詳解專欄
http://blog.csdn.net/column/details/huangwenchen-ios-sdk.html

前言,faulting 和 uniquing是理解CoreData的兩個比較關鍵的概念,這裡詳細的講解一下。
先簡單看看二者的概念

  • faulting 是一種CoreData降低記憶體使用量的機制,是惰性載入的一種。
  • Uniquing是輔助faulting的機制,它保證了在一個managed object context中只有一個managed object來表達一條記錄
faulting 限制對象圖的大小

一個fault在記憶體裡就是一個對象的預留位置,這個預留位置代表的對象並沒有完全取到記憶體裡。分為兩種:

  1. 一個managed object的fault就是相關類的對象,但是對象的持久化儲存的屬性沒有被初始化
  2. 一個relationship 的fault表示對應的集合的執行個體。

這樣的預留位置的方式降低了記憶體使用量,也不需要把fault對象相關的對象再取到記憶體裡。
例如,取出的一個employee,那麼員工的manager,department,reports預設都是fault來表示的

fault對於使用者來說是透明的,在使用者使用到對應的fault對象的持久化儲存的屬性時候,coredata會自動從磁碟取出對應資料,這個過程稱為Firing Faults.

Firing Faults的過程
  1. CoreData先到持久化儲存協調器的Cache裡尋找,如果有則返回,這個過程是否效率很高
  2. 如果沒有,則自動執行一次fetch,把對應的資料返回,並且加入到持久化儲存協調器的Cache裡

以下對managedObject的調用不會導致firing faults

isEqual:, hash, class, self, zone, isProxy, isKindOfClass:,isMemberOfClass:, conformsToProtocol:,respondsToSelector:, description,managedObjectContext, entity, objectID, isInserted, isUpdated, isDeleted, isFault.
關於Faulting的效能最佳化

毫無疑問,一次fire一個fault的效率是很低的。舉個例子
還是員工和部門的對象圖

取出一些員工,並且列印對應的Department name

NSFetchRequest * employeesFetch = <#A fetch request for Employees#>// The request should include a predicate -- if you don‘t have a predicate here,// you should probably just fetch all the Departments.NSArray *fetchedEmployees = [moc executeFetchRequest:employeesFetch error:&error];for (Employee *employee in fetchedEmployees){    NSLog(@"%@ -> %@ department", employee.name, employee.department.name);}

這樣會導致firing faults如下

Jack -> Sales [fault fires]Jill -> Marketing [fault fires]Benjy -> SalesGillian -> SalesHector -> Engineering [fault fires]Michelle -> Marketing

明顯,這樣的一次取一個的方式是效率很低的,CoreData提供了兩種解決方案

  • Batch faulting 一次處理一批
NSArray *array = [NSArray arrayWithObjects:fault1, fault2, ..., nil];NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self IN %@", array];
  • Pre-fetching 預提取
NSManagedObjectContext *context = /* get the context */;NSEntityDescription *employeeEntity = [NSEntityDescription    entityForName:@"Employee" inManagedObjectContext:context];NSFetchRequest *request = [[NSFetchRequest alloc] init];[request setEntity:employeeEntity];[request setRelationshipKeyPathsForPrefetching:    [NSArray arrayWithObject:@"department"]]
把已經初始化的對象轉換為fault

把已經初始化的對象轉為fault有很多好處

  • 降低記憶體使用量
  • 保證對象的資料都是最新的。(多線程情況下)

把一個對象轉為fault使用這個方法refreshObject:mergeChanges:,會把對應的持久化儲存屬性設為nil,斷開相關對象的強引用。

Uniquing

上文提到了:Uniquing是輔助faulting的機制,它保證了在一個managed object context中只有一個managed object來表達一條記錄.
例如:取出兩個Employee,對應都有代表fault的Department

在之後進行了firing faulting後,Department被取出,如果這兩個是同一個Department,那麼會自動指向一個對象。

如果,沒有這個機制,那麼會造成多個相同的Department存在記憶體裡,造成對象的不一致。

iOS CoreData詳解(四)Faulting and Uniquing

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.