COObjectGraphContext class documentation
COObjectGraphContext : NSObject <COItemGraph, COPersistentObjectContext>Overview
Conceptual Model
An object graph context is usually persistent (-branch is not nil), it manages the objects that represent the current branch state in memory, and tracks their changes between commits.
It tracks which objects in the object graph have been modified, which is what allows CoreObject to commit deltas instead of writing a fullsnapshot of every object in the object graph on every commit.
All the objects that belong to an object graph are called inner objects (including the root object), while objects in other object graphs are outer objects. A reference to an outer object is a cross-persistent root reference. For a more in-depth discussion, see Cross Persistent References section in COPersistentRoot.
Common Use Cases
The most common use case would be to check whether the object graph contains changes with -hasChanges , and more rarely to revert to the last committed state with -discardAllChanges e.g. when the user cancels some input in a dialog.
You rarely need to interact directly with COObjectGraphContext API, but object graph contexts are passed to COObject initializers to tell the new object to which context it belongs, see -[COObject initWithObjectGraphContext:] .
Item Graph Representation
COObjectGraphContext implements the COItemGraph protocol which allows viewing the COObjectGraphContext in a semi-serialized form (as a set of COItem objects), as well as the -setItemGraph: method which allows deserializing a given graph of COItems (reusing existing COObject instances if possible).
Transient Object Graph
To manage transient COObject instances, transient object graphs not bound to a branch or persistent root can be created. You can use them to hold an object graph state easily recreated in code (at launch time or on demand) without depending on an entire CoreObject stack (an editing context, a store etc.).
With COItemGraph protocol, COObject instances can be moved or copied accross persistent and transient object graphs.
In CoreObject, outer references (accross persistent object graphs) must point to a root object. Between a persistent and a transient object graph, this limit doesn't hold, you can refer to multiple objects and not just the root object (the root object is optional in a transient object graph).
If a transient COObject refers to a persistent one, there is no need to observe COObjectGraphContextWillRelinquishObjectsNotification, since the relationship cache will automatically update the references.
A transient object graph can be turned into a persistent one with -[COEditingContext insertNewPersistentRootWithRootObject:] , where the argument is an arbitrary object from the transient object graph.
Creation and Deletion
Persistent object graph contexts are usually created indirectly, each time a persistent root or branch is created, and their object graph is accessed. For example, with -[COPersistentRoot objectGraphContext] and -[COBranch objectGraphContext] .
To create transient object graphs, use -init , -initWithModelDescriptionRepository:, or +objectGraphContext.
A persistent object graph is deleted in the store, when the branch that owns it is deleted (see -[COBranch setDeleted:] ). For transient object graphs, all their content is lost when they are deallocated.
Object Equality
COObjectGraphContext does not override -hash or -isEqual:, so an object graph context is only considered equal to itself.
To compare the contents of two COObjectGraphContext instances you can do: COItemGraphEqualToItemGraph(ctx1, ctx2).
See also Object Equality section in COEditingContext.
Creation
- + (COObjectGraphContext *) objectGraphContext
Returns a new autoreleased transient object graph context using the main model description repository.
See also -[ETModelDescriptionRepository mainRepository] and -init .
- + (COObjectGraphContext *) objectGraphContextWithModelDescriptionRepository: (ETModelDescriptionRepository *)aRepo
Returns a new autoreleased transient object graph context using the given model description repository.
See also -initWithModelDescriptionRepository:.
- - (id) initWithBranch: (COBranch *)aBranch
Initializes a persistent object graph context owned by a branch.
- - (id) initWithModelDescriptionRepository: (ETModelDescriptionRepository *)aRepo
Initializes a transient object graph context using the given model description repository.
- - (id) init
Returns a new transient object graph context using the main model description repository.
See also -[ETModelDescriptionRepository mainRepository] .
Description
- - (NSString *) detailedDescription
Returns a description detailing the item graph representation (the serialized representation).
Type Querying
Metamodel Access
- - (ETModelDescriptionRepository *) modelDescriptionRepository
Returns the model description repository, which holds the metamodel that describes all the objects managed by the context.
Related Persistency Management Objects
- - (COBranch *) branch
The branch owning the object graph context.
For a transient object graph context, returns nil.
- - (COEditingContext *) editingContext
The persistent root owning the branch.
For a transient object graph context, returns nil.
Item Graph Protocol
- - (COItem *) itemForUUID: (ETUUID *)aUUID
Returns the immutable item that corresponds to the given inner object UUID.
- - (void) insertOrUpdateItems: (NSArray *)items
Updates the inner object graph to match the given item set.
The correspondance between a inner object and an item is decided using -[COObject UUID] and -[COItem UUID] .
When there is no inner object for an item UUID, a new inner object with the same UUID is inserted in the object graph, otherwise the existing inner object is updated. This must leave the object graph in a consistent state.
This marks the corresponding objects as inserted/object. and does not call -acceptAllChanges .
- - (void) setItemGraph: (id <COItemGraph>)aTree
Does the same than -insertOrUpdateItems: , but in addition discards change tracking (calls -acceptAllChanges).
Only loads objects from aTree reachable from a depth-first search starting at the root object.
As a special case, if both the receiver and aTree have a nil root object, loads all objects from aTree.
FIXME: Document more corner cases (what causes exceptions to be thrown)
Accessing the Root Object
- - (id) rootObject
The object serving as an entry point in the object graph.
The returned object is COObject class or subclass instance.
For a transient object graph context, can be nil.
For a persistent object graph context, a valid root object must be set before committing it.
This object UUID must remain the same in the entire persistent root history including the branches (and derived cheap copies). This is enforced in the store as well as in this property - it is a "set-once" property. An exception will be raised if the caller attempts to set it to something else.
The root object doesn't represent the core object. As such, use the persistent root UUID to refer to core objects and never [[self rootObject] UUID].
See also -rootItemUUID .
- - (void) setRootObject: (id)rootObject
The object serving as an entry point in the object graph.
The returned object is COObject class or subclass instance.
For a transient object graph context, can be nil.
For a persistent object graph context, a valid root object must be set before committing it.
This object UUID must remain the same in the entire persistent root history including the branches (and derived cheap copies). This is enforced in the store as well as in this property - it is a "set-once" property. An exception will be raised if the caller attempts to set it to something else.
The root object doesn't represent the core object. As such, use the persistent root UUID to refer to core objects and never [[self rootObject] UUID].
See also -rootItemUUID .
Change Tracking
- - (NSSet *) insertedObjectUUIDs
Returns the object UUIDs inserted since change tracking was cleared.
After a commit, returns an empty set.
- - (NSSet *) updatedObjectUUIDs
Returns the object UUIDs whose properties have been edited since change tracking was cleared.
After a commit, returns an empty set.
- - (BOOL) isUpdatedObject: (COObject *)anObject
- - (NSSet *) changedObjectUUIDs
Returns the union of the inserted and updated objects. See -insertedObjectUUIDs and -updatedObjectUUIDs .
After a commit, returns an empty set.
- - (BOOL) hasChanges
Returns whether the context contains uncommitted changes.
Inner object insertions and updates all count as uncommitted changes.
See also -discardAllChanges .
- - (void) discardAllChanges
If the receiver is owned by a branch, reloads to the current revision, clearing all changes.
Otherwise, all loaded objects are discarded (references to these objects become invalid as a result).
See also -acceptAllChanges and -[COBranch reloadAtRevision:] .
- - (void) acceptAllChanges
Conceptually, ends the current transaction and begins a new one.
To be exact, this clears the record of inserted and updated objects so the current state of the object graph is regarded as pristine. It's the caller's responsibility to have actually saved the changes somewhere before calling this (this is taken care of by COBranch.)
This method sends the COObjectGraphContextObjectsDidChangeNotification.
After calling this method, -hasChanges returns NO.
This method is semi-private; it is part of the API used by COBranch and framework users should normally never call this method.
Accessing Loaded Objects
- - (NSArray *) loadedObjects
All the inner objects loaded in memory.
The root object is included among the returned objects.
See also -loadedObjectForUUID: and -rootObject .