Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I've written a couple of helper methods (see below) to break the retain loops for a whole graph of objects by using introspection of the Entity model. You can use it after receiving a memory warning notification to release any memory held by the part of your core data model accessible through that particular object. </p> <pre><code>@interface CoreDataHelper(Private) + (void)faultObjectImpl:(NSManagedObject *)managedObject mergeChanges:(FaultChangeBehaviour)mergeChanges; + (void)faultObjectGraphForObject:(NSManagedObject *)managedObject handledObjects:(NSMutableArray *)handledObjects mergeChanges:(FaultChangeBehaviour)mergeChanges; @end @implementation CoreDataHelper typedef enum FaultChangeBehaviour { FaultChangeBehaviourIgnore, FaultChangeBehaviourReapply, FaultChangeBehaviourMerge } FaultChangeBehaviour; + (void)faultObjectGraphForObject:(NSManagedObject *)managedObject keepChanges:(BOOL)keepChanges { NSMutableArray *handledObjects = [NSMutableArray arrayWithCapacity:64]; FaultChangeBehaviour mergeBehaviour = keepChanges ? FaultChangeBehaviourReapply : FaultChangeBehaviourIgnore; [self faultObjectGraphForObject:managedObject handledObjects:handledObjects mergeChanges:mergeBehaviour]; } + (void)refreshObject:(NSManagedObject *)managedObject { [self faultObjectImpl:managedObject mergeChanges:FaultChangeBehaviourMerge]; } + (void)refreshObjectGraphForObject:(NSManagedObject *)managedObject { NSMutableArray *handledObjects = [NSMutableArray arrayWithCapacity:64]; [self faultObjectGraphForObject:managedObject handledObjects:handledObjects mergeChanges:FaultChangeBehaviourMerge]; } @end @implementation CoreDataHelper(Private) + (void)faultObjectImpl:(NSManagedObject *)managedObject mergeChanges:(FaultChangeBehaviour)mergeChanges { //Only fault if the object is not a fault yet and is not in a modified state or newly inserted (not saved yet) BOOL isFault = [managedObject isFault]; BOOL isTemporary = [[managedObject objectID] isTemporaryID]; BOOL isUpdated = [managedObject isUpdated]; NSDictionary *changedValues = [managedObject changedValues]; if (isUpdated &amp;&amp; (mergeChanges == FaultChangeBehaviourIgnore)) { NSLog(@"Warning, faulting object of class: %@ with changed values: %@. The changes will be lost!", NSStringFromClass([managedObject class]), changedValues); } if (!isFault &amp;&amp; !isTemporary) { [[managedObject managedObjectContext] refreshObject:managedObject mergeChanges:(mergeChanges == FaultChangeBehaviourMerge)]; if (mergeChanges == FaultChangeBehaviourReapply) { for (NSString *key in changedValues) { id value = [changedValues objectForKey:key]; @try { [managedObject setValue:value forKey:key]; } @catch (id exception) { NSLog(@"Could not reapply changed value: %@ for key: %@ on managedObject of class: %@", value, key, NSStringFromClass([managedObject class])); } } } } } + (void)faultObjectGraphForObject:(NSManagedObject *)managedObject handledObjects:(NSMutableArray *)handledObjects mergeChanges:(FaultChangeBehaviour)mergeChanges { if (managedObject != nil &amp;&amp; ![managedObject isFault] &amp;&amp; ![handledObjects containsObject:[managedObject objectID]]) { [handledObjects addObject:[managedObject objectID]]; NSEntityDescription *entity = [managedObject entity]; NSDictionary *relationShips = [entity relationshipsByName]; NSArray *relationShipNames = [relationShips allKeys]; for (int i = 0; i &lt; relationShipNames.count; ++i) { NSString *relationShipName = [relationShipNames objectAtIndex:i]; if (![managedObject hasFaultForRelationshipNamed:relationShipName]) { id relationShipTarget = [managedObject valueForKey:relationShipName]; NSRelationshipDescription *relationShipDescription = [relationShips objectForKey:relationShipName]; if ([relationShipDescription isToMany]) { NSSet *set = [NSSet setWithSet:relationShipTarget]; for (NSManagedObject* object in set) { [self faultObjectGraphForObject:object handledObjects:handledObjects mergeChanges:mergeChanges]; } } else { NSManagedObject *object = relationShipTarget; [self faultObjectGraphForObject:object handledObjects:handledObjects mergeChanges:mergeChanges]; } } } [self faultObjectImpl:managedObject mergeChanges:mergeChanges]; } } @end </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload