reference: http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html#//apple_ref/doc/uid/TP30001200-SW1
Object Lifetime Management
The Role of the Managed Object Context
his means that in general you cannot rely on a context to ensure the longevity of a
managed object instance, and you cannot rely on the existence of a managed object to ensure the longevity
of a context.
If you have finished with a managed object context, or for some other reason you want to “disconnect” a context from its persistent store coordinator, you should not set the context’s coordinator to nil:
// This will raise an exception
[myManagedObjectContext setPersistentStoreCoordinator:nil];
The exception to this rule is that a managed object context maintains a strong reference to any changed
(inserted, deleted, and updated) objects until the pending transaction is committed (with a save:) or discarded
(with a reset or rollback).
If you have finished with a managed object context, or for some other reason you want to “disconnect” a context from its persistent store coordinator, you should not set the context’s coordinator to nil:
// This will raise an exception
[myManagedObjectContext setPersistentStoreCoordinator:nil];
Instead, you should simply relinquish ownership of the context and allow it to be deallocated normally.
Breaking Relationship Strong Reference Cycles
To ensure that reference cycles are
broken, when you're finished with an object you can use the managed object context method
refreshObject:mergeChanges: to turn it into a fault.
Change and Undo Management
The undo manager associated with a context keeps strong references to any changed managed objects.
Change and Undo Management
A context keeps strong references to managed objects that have pending changes (insertions, deletions, or
updates) until the context is sent a save:, reset , rollback, or dealloc message, or the appropriate number
of undos to undo the change.
The undo manager associated with a context keeps strong references to any changed managed objects.
Relationships and Fetched Properties
There are two special variables you can use in the predicate of a fetched property—$FETCH_SOURCE and
$FETCHED_PROPERTY.
Core Data does not let you create relationships that cross stores. If you need to create a relationship from
objects in one store to objects in another, you should consider using fetched properties.
You use refreshObject:mergeChanges: to manually refresh
the properties—this causes the fetch request associated with this property to be executed again when the
object fault is next fired.
Relationship Fundamentals
You must define many-to-many relationships in both directions—that is,you must specify two
relationships, each being the inverse of the other. You can’t just define a to-many relationship in one
direction and try to use it as a many-to-many. If you do, you will end up with referential integrity problems.
A relationship specifies the entity, or the parent entity, of the objects at the destination. This can be the same
as the entity at the source (a reflexive relationship).
You can specify a relationship as being to-one or to-many. To-one relationships are represented by a reference to the destination object. To-many relationships are represented by mutable sets (although fetched properties are represented by arrays). Implicitly, “to-one” and “to-many” typically refer to “one-to-one” and “one-to-many” relationships respectively. A many-to-many relationship is one where a relationship and its inverse are both to-many.
You can specify a relationship as being to-one or to-many. To-one relationships are represented by a reference to the destination object. To-many relationships are represented by mutable sets (although fetched properties are represented by arrays). Implicitly, “to-one” and “to-many” typically refer to “one-to-one” and “one-to-many” relationships respectively. A many-to-many relationship is one where a relationship and its inverse are both to-many.
You can also put upper and lower limits on the number of objects at the destination of a to-many relationship.
The lower limit does not have to be zero. You can if you want specify that the number of employees in a
department must lie between 3 and 40. You also specify a relationship as either optional or not optional. If a
relationship is not optional, then in order to be valid there must be an object or objects at the destination of
the relationship.
Relationship Delete Rules
A relationship's delete rule specifies what should happen if an attempt is made to delete the source object.
For example, if you want to remove a department, you must ensure that all the employees in that
department are first transferred elsewhere (or fired!) otherwise the department cannot be deleted.
For example, if you delete a department, set the department for all the current members to null. This
only makes sense if the department relationship for an employee is optional, or if you ensure that you
set a new department for each of the employees before the next save operation.
For example, if you delete a department, fire all the employees in that department at the same time.
For example, if you delete a department, leave all the employees as they are, even if they still believe
they belong to that department.
Manipulating Relationships and Object Graph Integrity
anEmployee.department = newDepartment;
Alternatively, you can use:
Relationship Delete Rules
A relationship's delete rule specifies what should happen if an attempt is made to delete the source object.
Deny
If there is at least one object at the relationship destination, then the source object cannot be deleted.
If there is at least one object at the relationship destination, then the source object cannot be deleted.
Nullify
Set the inverse relationship for objects at the destination to null.
Set the inverse relationship for objects at the destination to null.
Cascade
Delete the objects at the destination of the relationship.
Delete the objects at the destination of the relationship.
No Action
Do nothing to the object at the destination of the relationship.
Do nothing to the object at the destination of the relationship.
Manipulating Relationships and Object Graph Integrity
anEmployee.department = newDepartment;
Alternatively, you can use:
[newDepartment addEmployeeObject:anEmployee];
Many-to-Many Relationships
Many-to-Many Relationships
Unidirectional Relationships
you should write:
[employee setValue:nil forKey:@"department"];
in general, you should avoid using unidirectional relationships. Bidirectional relationships
provide the framework with additional information with which to better maintain the object graph. If you do
want to use unidirectional relationships, you need to do some of this maintenance yourself. In the case above,
this would mean that after this line of code:
[managedObjectContext deleteObject:department];
[managedObjectContext deleteObject:department];
[employee setValue:nil forKey:@"department"];
Cross-Store Relationships
You must be careful not to create relationships from instances in one persistent store to instances in another
persistent store, as this is not supported by Core Data. If you need to create a relationship between entities in
different stores, you typically use fetched properties.
Fetched Properties
Fetched properties represent weak, one-way relationships.
Fetched properties represent weak, one-way relationships.
A fetched property is like a relationship, but it differs in several important ways:
- Rather than being a "direct" relationship, a fetched property's value is calculated using a fetch request. (The fetch request typically uses a predicate to constrain the result.)
- A fetched property is represented by an array, not a set. The fetch request associated with the property can have a sort ordering, and thus the fetched property may be ordered.
-
A fetched property is evaluated lazily, and is subsequently cached.
Non-Standard Persistent Attributes
he
principle behind the two approaches is the same: you present to consumers of your entity an attribute of the
type you want, and “behind the scenes” it’s converted into a type that Core Data can manage.
Transformable Attributes
Managed Object Validation
There are two types of validation—property-level and inter-property. You use property-level validation to
ensure the correctness of individual values; you use inter-property validation to ensure the correctness of
combinations of values.
Core Data Validation
Cocoa provides a basic infrastructure for model value validation. It requires you, though, to write code for all the constraints you want to apply. Core Data allows you to put validation logic into the managed object model.
If you do want to customize validation of individual properties, you use standard validation methods as defined by the NSKeyValueCoding protocol
Core Data Validation
Cocoa provides a basic infrastructure for model value validation. It requires you, though, to write code for all the constraints you want to apply. Core Data allows you to put validation logic into the managed object model.
If you do want to customize validation of individual properties, you use standard validation methods as defined by the NSKeyValueCoding protocol
Property-Level Validation
The NSKeyValueCoding protocol specifies a method—validateValue:forKey:error:—that provides
general support for validation methods in a similar way to that in which valueForKey: provides support for
accessor methods.
If you want to implement logic in addition to the constraints you provide in the managed object model, you
should not override validateValue:forKey:error:. Instead you should implement methods of the form
validate:error: .
If you do implement custom validation methods, you should typically not invoke them directly.
Instead you should call validateValue:forKey:error: with the appropriate key. This ensures that any
constraints defined in the managed object model are also applied.
-(BOOL)validateAge:(id*)ioValue error:(NSError **)outError{}
-(BOOL)validateAge:(id*)ioValue error:(NSError **)outError{}
The input value is a pointer to object reference (an id *). This means that in principle you can change the
input value
Inter-Property validation
NSManagedObject provides additional loci for validation—update, insertion, and deletion—through the validateFor... methods such as validateForUpdate:.
NSManagedObject provides additional loci for validation—update, insertion, and deletion—through the validateFor... methods such as validateForUpdate:.
Combining Validation Errors
It would appear that each employee has a separate department, and if you asked each employee for their
department in turn—turning the faults into regular objects—you would have two separate Department objects
in memory. However, if both employees belong to the same department (for example, "Marketing"), then Core
Data ensures that (in a given managed object context) only one object representing the Marketing department
is ever created. If both employees belong to the same department, their department relationships would both
therefore reference the same fault
Faulting and Uniquing
Faulting Limits the Size of the Object Graph
Faulting is a mechanism Core Data employs to reduce your application’s memory usage.
A fault is a placeholder object that
represents a managed object that has not yet been fully realized, or a collection object that represents a
relationship:
1. A managed object fault is an instance of the appropriate class, but its persistent variables are not yet
initialized.
2. A relationship fault is a subclass of the collection class that represents the relationship.
2. A relationship fault is a subclass of the collection class that represents the relationship.
To illustrate, consider an application that allows a user to fetch and edit details about a single employee. The
employee has a relationship to a manager and to a department, and these objects in turn have other
relationships. If you retrieve just a single Employee object from a persistent store, its manager, department,
and reports relationships are initially represented by faults. Figure 1 shows an employee’s department
relationship represented by a fault.
Fault handling is transparent—you do not have to execute a fetch to realize a fault.
If at some stage a persistent
property of a fault object is accessed, then Core Data automatically retrieves the data for the object and
initializes the object.
Firing Faults
Firing Faults
Turning Objects into Faults
Turning a realized object into a fault can be useful in pruning the object graph.
Turning a managed object into a fault releases unnecessary memory, sets its in-memory property values to nil, and breaks strong references to related objects.
You can turn a realized object into a fault with the refreshObject:mergeChanges: method. If you pass NO as the mergeChanges argument, you must be sure that there are no changes to that object’s relationships.
When an object turns into a fault, it is sent a didTurnIntoFault message. You may implement a custom didTurnIntoFault method to perform various “housekeeping” function
Uniquing Ensures a Single Managed Object per Record per Context
Turning a managed object into a fault releases unnecessary memory, sets its in-memory property values to nil, and breaks strong references to related objects.
You can turn a realized object into a fault with the refreshObject:mergeChanges: method. If you pass NO as the mergeChanges argument, you must be sure that there are no changes to that object’s relationships.
When an object turns into a fault, it is sent a didTurnIntoFault message. You may implement a custom didTurnIntoFault method to perform various “housekeeping” function
Uniquing Ensures a Single Managed Object per Record per Context
Core Data ensures that—in a given managed object context—an entry in a persistent store is associated with
only one managed object. The technique is known as uniquing.
No comments:
Post a Comment