Подтвердить что ты не робот

Почему NSDate в объекте, управляемом основными данными, преобразован в NSTimeInterval?

У меня есть объект с свойством типа Date, определенным в моем объекте xcdatamodeld. Почему он создал класс NSManagedObject с NSTimeInterval? И как мне установить NSDate на нем, а затем вернуть NSDate?

4b9b3361

Ответ 1

Я получаю это, если я проверяю флажок "Использовать скалярные свойства для примитивных типов данных", когда я создаю свои файлы.

Это связано с тем, что NSTimeInterval является двойной маскировкой, тогда как NSDate - это класс, который наследуется от NSObject.

Ответ 2

Изменить: по-видимому, dateWithTimeIntervalSince1970 предназначен только для NSDateFormatter. NSDate использует другую ссылку, чем NSDateFormatter, что, как объясняется в комментариях, в 2001 году. Извините за мое невежество.

Если у вас есть "Использовать скалярные свойства для примитивных типов данных", выбранных при создании подклассов NSManagedObject для ваших объектов, он будет использовать скалярные свойства, такие как int и float вместо NSNumber. Это включает NSDate; Он превратит NSDate в NSTimeInterval, который является просто двойным. Этот NSTimeInterval является временным интервалом с эпохи 1970-х годов, используемой Apple (если до 1970 года она, вероятно, отрицательна).

Довольно просто преобразовать NSTimeInterval обратно в NSDate, если вам это нужно, но если у вас нет огромной базы данных, вы можете не захотеть выбрать этот флажок.

Чтобы преобразовать этот временной интервал в NSDate, просто используйте [NSDate dateWithTimeIntervalSince1970: timeInterval];, где timeInterval - это то, что вы получаете из базы данных. Это можно поместить в ваш подкласс NSManagedObject, так что когда вы получите это свойство, вы все равно получите NSDate.

Ответ 3

Если вы хотите иметь смешанные объекты, которые используют как скалярные, так и нескалярные представления свойств, такие как int32_t для целых или логических свойств, но NSDate* для свойств даты, вам необходимо вручную отредактировать созданный управляемый объект .h файл.

Поэтому я обычно начинаю с создания классов управляемых объектов, проверяя параметр Использовать скалярные свойства для примитивных типов данных (поскольку у меня больше целых и булевых свойств, чем даты). Затем я редактирую созданный файл заголовка следующим образом:

MYEntity.h

@interface MYEntity : NSManagedObject
@property (nonatomic) int32_t index;
@property (nonatomic) NSTimeInterval date;
@end

затем становится:

@interface MYEntity : NSManagedObject
@property (nonatomic) int32_t index;
@property (nonatomic, retain) NSDate * date;
@end

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

MyEntity + Convenience.h:

@interface MYEntity (Convenience)
@property (nonatomic, readwrite) NSDate *theDate
@end

MyEntity + Convenience.h:

@implementation MYEntity (Convenience)

- (NSDate *)theDate {
    return [NSDate dateWithTimeIntervalSinceReferenceDate:self.date];
}

- (void)setTheDate:(NSDate *)theDate {
    self.date = [theDate timeIntervalSinceReferenceDate]
}

@end

Чтобы сделать код более читаемым в этом примере, я бы назвал исходное свойство dateTimeInterval в дизайнере модели данных и свойство удобства с его нужным именем: date.

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