Core data 核心数据:NSManagedObjectContextObjectsIDChangeNotification中的更改对象
是否可以在NSManagedObjectContextObjectsIDChangeNotification处理程序中更改托管对象的属性,而无需再次启动该处理程序? 我从服务器获取数据,RestKit将数据映射到核心数据。数据到达数据库后,我必须更改一些属性。 谢谢你的帮助 编辑: 这是我的密码。在循环中调用Core data 核心数据:NSManagedObjectContextObjectsIDChangeNotification中的更改对象,core-data,Core Data,是否可以在NSManagedObjectContextObjectsIDChangeNotification处理程序中更改托管对象的属性,而无需再次启动该处理程序? 我从服务器获取数据,RestKit将数据映射到核心数据。数据到达数据库后,我必须更改一些属性。 谢谢你的帮助 编辑: 这是我的密码。在循环中调用handledChangeNotification方法: - (void)addMyObserver { [[NSNotificationCenter defaultCenter]
handledChangeNotification
方法:
- (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;
}];
}
}
要在不触发更改通知的情况下修改核心数据对象,可以使用 基本访问器方法,例如 (请注意,此处需要对象值,标量值不起作用。) 但是如果没有任何不必要的副作用,你应该仔细考虑,因为 其他侦听器也不会被通知更改的值 另一种可能的解决方案是检查属性是否必须更改,
并仅在必要时进行修改。示例如何查看
NSManagedObject的子类YourPropertyName
-是您的类
@implementation YourPropertyName
@dynamic stringValueOfYourProperty;//for example
-(void)setStringValueOfYourProperty:(NSString *) _stringValueOfYourProperty
{
[self willChangeValueForKey:@"stringValueOfYourProperty"];
[self setPrimitiveValue: _stringValueOfYourProperty forKey:@"stringValueOfYourProperty"];
[self didChangeValueForKey:@"stringValueOfYourProperty"];
}
然后在代码中的任何地方使用setStringValueOfYourProperty
。下面的代码是我脑子里想不出来的,没有经过测试,但我会这样做
@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;
}];
}
}
我成功使用的一个解决方法是(我还没有注意到副作用。如果我错了,请告诉我)
在didChange
CoreData通知回调中,我将所有更新的对象保存在一个全局数组中李>
在willSave
CordData通知回调中,我修改了保存在第1点的对象
将再次调用didChange
回调,并将自动跳过willSave
didSave
CoreData通知回调,如果需要李>
您是否考虑过使用单独的MOC进行导入?这样你就可以观察环境来做出改变。我听说过,但我认为在这种情况下不建议这样做,正如你提到的,你可能会有副作用。我想,在检索到数据请求的响应后,我将手动进行距离更新。谢谢你的回答。这个中断会撤消吗?@malhal:我不知道。但是didChangeValueForKey
会再次触发更改通知,这是OP试图避免的。如果应用程序是多用户的,没有didChangeValueForKey
你就不会得到副作用?
@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;
}];
}
}