Получить дату изменения для NSManagedObject в Core Data? - PullRequest
15 голосов
/ 28 апреля 2011

Помимо добавления свойства NSDate к каждому объекту в моем хранилище базовых данных, существует ли программный способ получения даты изменения для любого объекта?

Ответы [ 5 ]

21 голосов
/ 28 апреля 2011

Нет, вы должны добавить дату и управлять ей самостоятельно.Вы можете использовать переопределение -willSave в вашем управляемом объекте для обновления отметки времени, но прочитайте документацию API для NSManagedObject на -willSave, чтобы узнать, как обновлять, не вызывая цикл willSave (в документах даже говорится о случае обновления отметки времени),В документах также упоминается использование NSManagedObjectContextWillSaveNotification, но это может быть более сложной задачей, чем простая проверка, чтобы не устанавливать метку времени слишком быстро.

6 голосов
/ 30 октября 2015

Я лично проверяю, был ли изменен updatedAt, и если да, то я его больше не трогаю. Таким образом я разрываю петлю willSave.

- (void)awakeFromInsert {
    [super awakeFromInsert];

    self.primitiveUpdatedAt = [NSDate date];
}

- (void)willSave {
    [super willSave];

    if(![self isDeleted] && self.changedValues[@"updatedAt"] == nil) {
        self.updatedAt = [NSDate date];
    }
}
6 голосов
/ 04 марта 2015

Обратите внимание, это решение предполагает, что у нас есть свойство под названием dateUpated в модели.

Вместо того, чтобы обрабатывать это на отдельных объектах. Я бы справился с этим через уведомление. Документация Apple также предлагает этот способ.

1. Зарегистрироваться для уведомления NSManagedObjectContextWillSaveNotification

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(willSaveContext:)         
                                             name:NSManagedObjectContextWillSaveNotification 
                                           object:nil];

2 Установите свойство для updatedDate в методе наблюдателя для каждого обновленного объекта.

- (void)willSaveContext:(NSNotification *)notification{

    NSManagedObjectContext *context = [notification object];
    NSSet *updatedObject = [context updatedObjects];

    for (NSManagedObject *managedObject in [updatedObject allObjects]) {
        if ([[managedObject.entity propertiesByName] objectForKey:@"dateUpdated"]) {
            [managedObject setValue:[NSDate date] forKey:@"dateUpdated"];
        }

    }

}
2 голосов
/ 19 декабря 2011

Я нашел этот вопрос полезным для начала работы по настройке атрибута для даты, измененной в Базовых данных. В процессе я пришел к нескольким советам, которые также могут помочь:

(Совет 1: избегать рекурсии willSave)

  • Еще один способ избежать цикла willSave - написать собственную подпрограмму для сохранения контекста, которая перебирает свои обновленные объекты, ища те, которые имеют свойство dateModified, и устанавливая его. Выполните фактические вызовы commitEditing и save после этого цикла. Не беспокойтесь о WillSave.

(Совет 2: обновление в режиме реального времени - но с отменой не работает)

  • Если вам нужно обновление в реальном времени для отображения даты, измененной для пользователя в таблице, вы также можете установить dateModified в своем регистре переключения (или что-то еще) для столбца с измененной датой в методе делегата objectValueForTableColumn willDisplayCell для iOS).

  • Там проверьте, обновлен ли объект для этой строки, и, если да, установите dateModified. Я сомневаюсь, что чек if (obj isUpdated) очень дорогой. Но обязательно делайте это только для соответствующего столбца, чтобы не повторять его без необходимости.

  • Вернуть любое строковое представление, которое вы используете для столбца. Чтобы избежать очевидных различий между временем фактического изменения и установленной датой, показывайте только дату, а не время.

  • Это приведет к тому, что dateModified будет обновляться всякий раз, когда пользователь делает выбор таблицы, а также при перезагрузке таблицы. Что не является идеальным - если пользователь изменяет атрибут, который не представлен в таблице, столбец не будет обновляться, пока не будет сделан выбор. Но это достаточно быстро и намного проще, чем реализация обширной схемы КВО.

  • (Вы все равно захотите установить дату в подпрограмме сохранения, чтобы отследить изменения, которые не видны в таблице.)

  • ОТЛОЖЕНИЕ СЛОЖНО: К сожалению, менеджер по отмене будет рассматривать изменение метода делегата таблицы на dateModifed как событие для себя. Впоследствии вызов отмены просто отменяет последнее изменение dateModified - снова и снова. Я попытался преодолеть это, добавив трекер и проверку непустого словаря changeValues, чтобы гарантировать, что dateModified будет установлен только один раз перед сохранением. Это сработало для удаления удалений, но не для регулярных правок. Таким образом, нет быстрого способа выполнить предварительное сохранение dateModified в реальном времени.

0 голосов
/ 03 сентября 2015

Если кому-то нужен простой способ сделать это в Swift: я написал в блоге о простом классе UpdateListener, чтобы обновить все свойства updateDate и insertDate. Вы можете найти весь класс в этой сущности . Все, что вам нужно сделать, это вызвать UpdateListener.setupSharedInstance() в методе application(:didFinishLaunchingWithOptions:) вашего приложения-делегата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...