Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

core data: change objects in NSManagedObjectContextObjectsDidChangeNotification

Tags:

core-data

Is it possible to change attributes of managed objects in NSManagedObjectContextObjectsDidChangeNotification handler without firing the handler again? I get the data from our server and RestKit maps the data into Core Data. I have to change some attributes after the data arrives in my database. Thanks for help.

Edit: This is my code. The handleDidChangeNotificationmethod is called in a cycle:

- (void)addMyObserver
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(handleDidChangeNotification:)
                                                 name:NSManagedObjectContextObjectsDidChangeNotification
                                               object:self.objectManager.managedObjectStore.mainQueueManagedObjectContext];
}

- (void)handleDidChangeNotification:(NSNotification *)notification
{
    NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
    NSSet *deletedObjects = [[notification userInfo] objectForKey:NSDeletedObjectsKey];
    NSSet *insertedObjects = [[notification userInfo] objectForKey:NSInsertedObjectsKey];

    // modifiedObjects with store entity:
    NSSet *modifiedObjects = [updatedObjects setByAddingObjectsFromSet:insertedObjects];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF isKindOfClass: %@", [MyStore class]];
    NSSet *modifiedStoreObjects = [modifiedObjects filteredSetUsingPredicate:predicate];

    if (modifiedStoreObjects.count > 0)
    {
        [modifiedStoreObjects enumerateObjectsUsingBlock:^(MyStore *store, BOOL *stop)
         {
             store.distanceValue = 1000;
         }];
    }
}
like image 941
Ralf Hundewadt Avatar asked May 12 '26 02:05

Ralf Hundewadt


2 Answers

To modify a Core Data object without firing the change notifications, you can use the primitive accessor methods, e.g.

[store setPrimitiveValue:@1000 forKey:@"distanceValue"];

(Note that an object value is required here, a scalar value does not work.)

But you should consider carefully if there are not any unwanted side effects, because other listeners will also not be notified about the changed value.

Another possible solution might be to check if the attribute has to be changed at all, and modify only if necessary.

like image 183
Martin R Avatar answered May 13 '26 20:05

Martin R


The following code is off the top of my head, not tested, but this is how I would go.

@interface MyStoreCoordinator () {
    bool _changingValue;
}
@end

@implementation MyStoreCoordinator

- (void)addMyObserver
{
    _changingValue = NO;
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(handleDidChangeNotification:)
                                                 name:NSManagedObjectContextObjectsDidChangeNotification
                                               object:self.objectManager.managedObjectStore.mainQueueManagedObjectContext];
}

- (void)handleDidChangeNotification:(NSNotification *)notification
{
    if (_changingValue)
    {
        return;
    }

    NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
    NSSet *deletedObjects = [[notification userInfo] objectForKey:NSDeletedObjectsKey];
    NSSet *insertedObjects = [[notification userInfo] objectForKey:NSInsertedObjectsKey];

    // modifiedObjects with store entity:
    NSSet *modifiedObjects = [updatedObjects setByAddingObjectsFromSet:insertedObjects];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF isKindOfClass: %@", [MyStore class]];
    NSSet *modifiedStoreObjects = [modifiedObjects filteredSetUsingPredicate:predicate];

    if (modifiedStoreObjects.count > 0)
    {
        [modifiedStoreObjects enumerateObjectsUsingBlock:^(MyStore *store, BOOL *stop)
         {
             _changingValue = YES;
             store.distanceValue = 1000;
             _changingValue = NO;
         }];
    }
}
like image 23
Owen Godfrey Avatar answered May 13 '26 21:05

Owen Godfrey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!