在 NSManagedObjectsDidChangeNotification 创建无限循环后设置 lastModificationDate 属性

2024-02-05

我添加了一个最后修改日期属性到我的所有实体以避免同步时重复UIManagedDocument使用 iCloud,我发现如果我使用离线设备 (iPad) 创建新实体,同时使用另一个在线设备 (iPhone) 创建相同的实体,就会发生这种情况。

我想在对象发生变化时设置此属性,所以我订阅了NSManagedObjectContextObjectsDidChangeNotification。我编写的用于设置lastModifiedDate的代码会创建一个无限循环,因为通过设置lastModificationDate属性,它会创建一个更改,该更改将由NSManagedObjectContextObjectsDidChangeNotification再次通知,依此类推......

可以修复吗?有更好的方法来实现我的目标吗?我应该子类化 ManageObjectContext 并覆盖吗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在托管对象子类中也会遇到同样的问题。 Apple 文档为willSave states:

例如,如果您设置了上次修改时间戳,则应该检查 无论您之前在同一保存操作中设置它,还是 现有时间戳不小于与 当前时间。通常最好计算一次时间戳 对于所有正在保存的对象(例如,响应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属性,否则 你必须检查对象的类。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 NSManagedObjectsDidChangeNotification 创建无限循环后设置 lastModificationDate 属性 的相关文章

随机推荐