【问题标题】:Core Data before Update callback更新回调之前的核心数据
【发布时间】:2014-06-09 12:20:25
【问题描述】:

我的实体都具有createdAtupdatedAt 属性。我要做的是在插入/更新时自动设置这些属性的值。

经过一番研究,我发现有一个awakeFromInsert 方法可以用来在创建新对象时自动设置createdAt 属性的值。

但是,我找不到任何类似的更新对象的方法。所以我该怎么做?我每次都必须手动更新updatedAt 属性吗?

【问题讨论】:

    标签: objective-c core-data callback


    【解决方案1】:

    这取决于您想要实现的目标。仅在保存时更新您可以在以下位置进行:

    -(void)willSave;

    记住在这个地方修改属性会再次调用willSave。因此,您只需更新一次updatedAt。另外,您必须检查该对象是否未被删除 - isDeleted

    您还可以观察所有属性并将updatedAt 设置为真正更新而不是保存的日期。

    【讨论】:

    • 感谢您的快速回答。但是,我最终做了一些稍微不同的事情(请参阅我自己对问题的回答)。
    • 在 +load 上全局执行此类操作是 imo 坏主意。对我来说,更好的地方是在你的 appDelegate 或任何你有核心数据管理的地方观看 managedObjectContext 上的此类通知。
    【解决方案2】:

    我最终在 StackOverflow(https://stackoverflow.com/a/10723861/123016https://stackoverflow.com/a/4590190/123016)上找到了类似的问题/答案。我根据自己的需要调整了建议的解决方案。

    我首先做的是创建一个抽象实体,我将其用作所有其他实体的父类。这个抽象类有两个属性:createdAtupdatedAt

    然后我将以下代码添加到抽象类的实现中:

    - (void)awakeFromInsert
    {
        [super awakeFromInsert];
    
        self.createdAt = [NSDate date];
    }
    
    + (void)load
    {
        @autoreleasepool {
            [[NSNotificationCenter defaultCenter] addObserver:(id)self.class
                                                     selector:@selector(objectContextWillSave:)
                                                         name:NSManagedObjectContextWillSaveNotification
                                                       object:nil];
        }
    }
    
    + (void)objectContextWillSave:(NSNotification *)notification
    {
        NSManagedObjectContext *context              = [notification object];
        NSSet                  *allObjects           = [context.insertedObjects setByAddingObjectsFromSet:context.updatedObjects];
        NSPredicate            *predicate            = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@", [self class]];
        NSSet                  *allModifiableObjects = [allObjects filteredSetUsingPredicate:predicate];
    
        [allModifiableObjects makeObjectsPerformSelector:@selector(setUpdatedAt:) withObject:[NSDate date]];
    }
    

    除了我将父类抽象化之外,这与两个答案的组合代码完全相同。

    【讨论】:

    • 为所有托管对象创建一个抽象的父实体是个坏主意。它们都将存储在同一个 SQL 表中,您的数据库性能将受到影响。
    • 您最好创建一些其他对象来监听通知,如果更新的对象具有适当的属性,则更新相关属性
    • 啊!没想到这一点(我的坏举动)......但是,如果我创建了另一个监听通知然后更新相关属性的对象,我不会更新记录两次吗?如果是这样的话,那不会也影响性能吗?
    • 我所说的性能是用于获取、查找和插入以及几乎所有内容。就上面发生的代码而言,数据库更新将完全相同 - 您所做的只是通过为通知订阅许多不同的类来避免重复自己。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    • 2013-02-22
    • 1970-01-01
    相关资源
    最近更新 更多