Каков тип булевых атрибутов в объектах Core Data?
Я использую Core Data программно (т.е. не используя файлы модели данных t20 > ) почти так же, как показано в Apple Учебное пособие по основным данным. Поэтому моя проблема заключается в том, что когда я пытаюсь добавить атрибут к объекту с типом NSBooleanAttributeType
, он становится немного ошибкой. Когда я добавлю его в заголовочный файл подкласса NSManagedObject
(в учебнике это будет Run.h
) как
@property (retain) BOOL *booleanProperty;
сбой компиляции, говоря error: property 'booleanProperty' with 'retain' attribute must be of object type
.
Кажется, что некоторые места в Cocoa используют объекты NSNumber
для представления булевых элементов, поэтому я попытался установить его на
@property (retain) NSNumber *booleanProperty;
вместо этого. Однако это вызывает следующие ошибки времени выполнения:
*** -[NSAttributeDescription _setManagedObjectModel:]: unrecognized selector sent to instance 0x101b470
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSAttributeDescription _setManagedObjectModel:]: unrecognized selector sent to instance 0x101b470'
Используя GDB, я могу отследить это обратно к строке в моем исходном коде, где я добавляю свой объект к модели управляемого объекта:
[DVManagedObjectModel setEntities:[NSArray arrayWithObjects:myEntityWithABooleanAttribute, myOtherEntity]];
Итак, мой вопрос заключается в следующем: какой тип я должен установить booleanProperty в свой собственный заголовок класса?
Ответы
Ответ 1
Try:
@property (nonatomic) BOOL booleanProperty;
Проблема заключалась в том, что вы использовали сохранение в определении свойства. Для этого у вас должно быть свойство класса Objective-C (он должен понимать метод "сохранить" ). BOOL - это не класс, а псевдоним для подписанного char.
Ответ 2
Я бы не рекомендовал метод, предложенный Diederik Hoogenboom (я получил ошибку, хотя мой основной атрибут данных был установлен как Boolean).
Стоит отметить, что хотя эта строка будет работать для пользовательского объекта, она не будет работать для подкласса NSManagedObject:
@property (nonatomic) BOOL booleanProperty;
Ваше свойство должно быть установлено следующим образом:
@property (nonatomic, retain) NSNumber *booleanProperty;
Когда я копирую объявления метода для логического типа (используя метод, предложенный Джим Коррейей), геттер и сеттер печатаются как:
NSNumber:-(NSNumber *)booleanProperty;
-(void)setBooleanProperty:(NSNumber *)value;
... это то, что Boolean свойство в данных ядра задано как, и вам нужно проверить свою собственность примерно так:
-(BOOL)validateBooleanProperty:(NSNumber **)toValidate error:(NSError **)outError
{
int toVal = [*toValidate intValue];
if ( (toVal < 0) || (toVal > 1) )
{
NSString *errorString = NSLocalizedStringFromTable(@"Boolean Property", @"TheObject", @"validation: not YES or NO");
NSDictionary *userInfoDict = [NSDictionary dictionaryWithObject:errorString forKey:NSLocalizedDescriptionKey];
NSError *error = [[[NSError alloc] initWithDomain:NSCocoaErrorDomain code:-1 userInfo:userInfoDict] autorelease];
*outError = error;
return NO;
}
return YES;
}//END
... не забудьте включить объявление validateBooleanProperty в файл заголовка. Методы setter и getter хранят и извлекают ваше свойство с помощью ключа (id) primitiveValueForKey: (NSString *).
Наконец, вам нужно явно вызвать метод проверки из любого делегата диспетчера/приложения диспетчера приложений, из которого вы устанавливаете объект:
NSNumber *boolProp = [[[NSNumber alloc] initWithInt :0] autorelease];
NSError *valError = nil;
if ([TheObject validateBooleanProperty:&boolProp error:&valError] == YES)
{
[TheObject setBooleanProperty :boolProp];
}
Ответ 3
В заголовке
@property (nonatomic, retain) NSNumber *booleanProperty;
В реализации
@dynamic booleanProperty;
Чтобы установить значение true...
self.booleanProperty = [NSNumber numberWithBool:YES];
Чтобы установить его на false...
self.booleanProperty = [NSNumber numberWithBool:NO];
Чтобы сравнить его с литералом true boolean:...
self.booleanProperty.boolValue == YES;
Чтобы сравнить его с литералом false boolean:...
self.booleanProperty.boolValue == NO;
Для получения дополнительной информации: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/nsnumber_Class/Reference/Reference.html#//apple_ref/occ/clm/NSNumber/numberWithBool:
Ответ 4
Одним из лучших способов генерации правильных аксессуаров в вашем подклассе NSManagedObject является отображение контекстного меню атрибута или свойства в инструменте моделирования данных и выбор одной из следующих команд:
- Объявление метода копирования в буфер обмена
- Реализация метода копирования в буфер обмена
- Копирование деклараций метода Obj-C 2.0 в буфер обмена
- Скопируйте реализацию метода Obj-C 2.0 в буфер обмена
Ответ 5
Пусть Xcode 4.0 решит для вас.
В Xcode: выберите Entity из вашего файла *.xcdatamodel.
Выберите "Редактор" > "Создать подкласс NSMagedObject"...
Xcode объявляет ваши логические объекты как тип NSNumber.
Изменить: Мне любопытно, какая мотивация для смягчения xcdatamodel? Кто-нибудь?
Ответ 6
Атрибут типа Boolean в NSManagedObject имеет тип NSCFBoolean. Это частный подкласс NSNumber.
Ответ 7
Я не знаю, если это только опечатка с вашей стороны, но это:
[NSArray arrayWithObjects:myEntityWithABooleanAttribute, myOtherEntity]
определенно неверно. Последний параметр этого метода всегда должен быть равен нулю.
Ответ 8
Использовать NSNumber. В структуре CoreData нет bool.