IOS CoreData (4) Faulting and Uniquing, coredatafaulting
Original blog, reprinted, please indicate the source
Blog.csdn.net/hello_hwc
Welcome to my iOS SDK detail Column
Http://blog.csdn.net/column/details/huangwenchen-ios-sdk.html
Faulting and uniquing are two key concepts for understanding CoreData.
Let's take a look at the concepts of the two.
- Faulting is a mechanism that reduces the memory usage of CoreData and is a kind of inert loading.
- Uniquing is a mechanism for assisting faulting. It ensures that only one managed object in a managed object context can express one record.
Faulting limits the object graph size
A fault is a placeholder for an object in the memory. This placeholder indicates that the object is not fully retrieved from the memory. There are two types:
This placeholder method reduces memory usage and does not need to retrieve the objects related to the fault object to the memory.
For example, if an employee is retrieved, the employee's manager, department, and reports are represented by fault by default.
Fault is transparent to users. When you use the persistent storage attribute of the corresponding fault object, coredata automatically retrieves the corresponding data from the disk. This process is called Firing Faults.
Firing Faults Process
The following calls to managedObject will not cause firing faults
isEqual:, hash, class, self, zone, isProxy, isKindOfClass:,isMemberOfClass:, conformsToProtocol:,respondsToSelector:, description,managedObjectContext, entity, objectID, isInserted, isUpdated, isDeleted, isFault.
Faulting Performance Optimization
There is no doubt that the efficiency of a single fire fault is very low. For example
Or the employee and department object Diagram
Retrieve some employees and print the corresponding 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);}
This will cause firing faults to be as follows:
Jack -> Sales [fault fires]Jill -> Marketing [fault fires]Benjy -> SalesGillian -> SalesHector -> Engineering [fault fires]Michelle -> Marketing
Obviously, this method is very inefficient. CoreData provides two solutions.
- Batch faulting processes a Batch at a time
NSArray *array = [NSArray arrayWithObjects:fault1, fault2, ..., nil];NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self IN %@", array];
- Pre-fetching Pre-Extraction
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"]]
Convert initialized objects to fault
Converting an initialized object to a fault has many advantages.
- Reduce memory usage
- Ensure that the object data is up-to-date. (Multithreading)
Convert an object to fault. Use this method.refreshObject:mergeChanges:
, The corresponding persistent storage attribute is set to nil, disconnect the strong reference of the relevant object.
Uniquing
As mentioned above, Uniquing is a mechanism for assisting faulting. It ensures that only one managed object in a managed object context can express one record.
For example, if two employees are taken out, each Department represents the fault.
After firing faulting is performed, the Department is taken out. If the two are the same Department, the Department automatically points to an object.
Without this mechanism, multiple identical departments will exist in the memory, resulting in inconsistent objects.