3

是否可以在不再次触发处理程序的情况下更改 NSManagedObjectContextObjectsDidChangeNotification 处理程序中托管对象的属性?我从我们的服务器获取数据,RestKit 将数据映射到 Core Data。数据到达我的数据库后,我必须更改一些属性。感谢帮助。

编辑:这是我的代码。循环调用该handleDidChangeNotification方法:

- (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;
         }];
    }
}
4

4 回答 4

3

要在不触发更改通知的情况下修改 Core Data 对象,您可以使用 原始访问器方法,例如

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

(注意这里需要一个对象值,标量值不起作用。)

但是如果没有任何不需要的副作用,您应该仔细考虑,因为其他侦听器也不会收到有关更改值的通知。

另一种可能的解决方案可能是检查是否必须更改属性,并仅在必要时进行修改。

于 2013-10-14T12:32:50.053 回答
1

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;
         }];
    }
}
于 2013-11-05T00:49:29.530 回答
0

示例如何查看NSManagedObject. YourPropertyName- 是你的班级

@implementation YourPropertyName

@dynamic stringValueOfYourProperty;//for example

-(void)setStringValueOfYourProperty:(NSString *) _stringValueOfYourProperty
{
    [self willChangeValueForKey:@"stringValueOfYourProperty"];
    [self setPrimitiveValue: _stringValueOfYourProperty forKey:@"stringValueOfYourProperty"];
    [self didChangeValueForKey:@"stringValueOfYourProperty"];
}

然后只需setStringValueOfYourProperty在代码中的任何位置使用。

于 2013-10-14T13:55:59.123 回答
0

我成功使用的一种解决方法是(我还没有注意到副作用。如果我错了,请告诉我)。

  1. didChangeCoreData 通知回调中,我将所有更新的对象保存在一个全局数组中。
  2. willSaveCordData 通知回调中,我修改了第 1 点保存的对象
  3. 回调将didChange被再次调用并willSave自动跳过
  4. didSave如果需要,CoreData 通知回调!
于 2019-10-27T15:10:46.423 回答