是否可以在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;
}];
}
}
答案 0 :(得分:3)
要修改Core Data对象而不触发更改通知,您可以使用 原始访问者方法,例如
[store setPrimitiveValue:@1000 forKey:@"distanceValue"];
(请注意,此处需要对象值,标量值不起作用。)
但是你应该仔细考虑是否有任何不必要的副作用,因为 其他听众也将不收到有关更改后值的通知。
另一种可能的解决方案可能是检查是否必须更改属性, 并在必要时进行修改。
答案 1 :(得分:1)
以下代码不在我的脑海中,未经过测试,但这就是我要去的方式。
@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;
}];
}
}
答案 2 :(得分: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
。
答案 3 :(得分:0)
我成功使用的一种解决方法是(我尚未注意到副作用。如果我错了,请告诉我)。
didChange
CoreData通知回调中,我将所有更新的对象保存在全局数组中。 willSave
CordData通知回调中,我修改了保存在第1点的对象didChange
回调将再次被调用,willSave
将被自动跳过didSave
CoreData通知回调(如果需要)!