У меня есть объект с свойством типа Date, определенным в моем объекте xcdatamodeld. Почему он создал класс NSManagedObject с NSTimeInterval? И как мне установить NSDate на нем, а затем вернуть NSDate?
Почему NSDate в объекте, управляемом основными данными, преобразован в NSTimeInterval?
Ответ 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
.
Второй подход, очевидно, также работает наоборот. Вы можете экспортировать объекты с нескалярными свойствами, а затем предоставить удобное скалярное свойство, получатель и сеттер которого получают доступ к исходному нескалярному свойству.