我想在对象发生变化时设置此属性,因此我订阅了NSManagedObjectContextObjectsDidChangeNotification.我编写的用于设置lastModifiedDate的代码创建了一个无限循环,因为通过设置lastModificationDate属性,它创建了一个更改,NSManagedObjectContextObjectsDidChangeNotification将再次通知该等更改…
有可能解决它吗?有没有更好的方法来实现我的目标?我应该将managedObjectContext子类化并覆盖willSave:?
//At init... [[NSNotificationCenter defaultCenter] addObserver:applicationDatabase selector:@selector(objectsDidChange:) name:NSManagedObjectContextObjectsDidChangeNotification object:applicationDatabase.managedDocument.managedObjectContext]; (void) objectsDidChange: (NSNotification*) note { // creates an infinite loop NSDate *dateOfTheLastModification = [NSDate date]; NSMutableArray *userInfoKeys = [[note.userInfo allKeys] mutableCopy]; for(int i=0; i< userInfoKeys.count;i++){ NSString *key = [userInfoKeys objectAtIndex:i]; if([key isEqualToString:@"managedObjectContext"]){ [userInfoKeys removeObject:key]; } } for(NSString *key in userInfoKeys){ NSArray *detail = [note.userInfo objectForKey:key]; for (id object in detail){ [object setValue:dateOfTheLastModification forKey:@"lastModifiedDate"]; } }要避免无限循环,可以使用.设置上次修改日期
原始访问者:
[object setPrimitiveValue:dateOfTheLastModification forKey:@"lastModifiedDate"];
因为这不会触发另一个“更改”通知.但这也意味着
没有观察者会看到变化.
覆盖托管对象子类中的willSave会遇到同样的问题.
willSave的Apple文档说明:
For example, if you set a last-modified timestamp, you should check
whether either you previously set it in the same save operation, or
that the existing timestamp is not less than a small delta from the
current time. Typically it’s better to calculate the timestamp once
for all the objects being saved (for example, in response to an
NSManagedObjectContextWillSaveNotification
).
所以你应该注册NSManagedObjectContextWillSaveNotification,
并在托管对象中的所有更新和插入的对象上设置时间戳
上下文.注册的方法可能如下所示:
-(void)contextWillSave:(NSNotification *)notify { NSManagedObjectContext *context = [notify object]; NSDate *dateOfTheLastModification = [NSDate date]; for (NSManagedObject *obj in [context insertedObjects]) { [obj setValue:dateOfTheLastModification forKey:@"lastModifiedDate"]; } for (NSManagedObject *obj in [context updatedObjects]) { [obj setValue:dateOfTheLastModification forKey:@"lastModifiedDate"]; } }
这假定您的所有实体都具有lastModifiedDate属性,否则你必须检查对象的类.