Question

I am trying to turn objects into Faults with the following code, but failed.

User.m

@implementation User

...

-(void)memoryWarningHandle{
    if (![self.avatar isFault]) {
       [self.managedObjectContext refreshObject:self.avatar mergeChanges:NO];

        if ([self.avatar isFault]) {
           NSLog(@"isFault");
         // Never went into here
        }
    }
}
...

Here User is an Entity and avatar is an Attribute of User.

As said in the Apple Document:

refreshObject:mergeChanges: Updates the persistent properties of a managed object to use the latest values from the persistent store.

  • (void)refreshObject:(NSManagedObject *)object mergeChanges:(BOOL)flag Parameters object A managed object. flag A Boolean value.

If flag is NO, then object is turned into a fault and any pending changes are lost. The object remains a fault until it is accessed again, at which time its property values will be reloaded from the store or last cached state.

If flag is YES, then object’s property values are reloaded from the values from the store or the last cached state then any changes that were made (in the local context) are re-applied over those (now newly updated) values. (If flag is YES the merge of the values into object will always succeed—in this case there is therefore no such thing as a “merge conflict” or a merge that is not possible.)

The avatar must be fault after [self.managedObjectContext refreshObject:self.avatar mergeChanges:NO]; is called, but it is not. What's going on here? Any help will be appreciated!

EDIT 1 I test the code as following:

-(void)memoryWarningHandle{
    self.avatar = [UIImage imageNamed:@"avatar.png"];
    NSLog(@"self.avatar :%@",self.avatar);
    NSLog(@"self.managedObjectContext :%@",self.managedObjectContext);
    if (![self.avatar isFault]) {
       [self.managedObjectContext refreshObject:self.avatar mergeChanges:NO];

       if ([self.avatar isFault]) {
          NSLog(@"isFault");
        // Never went into here
       }
    }
}

NSLog Results:

2013-05-23 11:58:30.072 myApp[10967:907] self.avatar :<UIImage: 0x1d5f6e20>
2013-05-23 11:58:30.947 myApp[10967:907] self.managedObjectContext :<NSManagedObjectContext: 0x1e898c10>
Was it helpful?

Solution

UIImage is not a subclass of NSManagedObject you cannot refresh is, nor does it respond to isFault.
In any case, you cannot fault a specific property on a NSManagedObject, you must fault the entire object.

try [[self managedObjectContext] refreshObject:self mergeChanges:NO] to fault your entire object.

If you like to fault only the picture data, add a to-one relationship (say imageContainer) to an entity that hold the image data in a property (say imageData), and then refresh that relationship on the object like so:

[[self managedObjectContext] refreshObject:self.imageContainer mergeChanges:NO]

You should have got an exception in your code like: Unrecognized selector sent to instance ...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top