Какой тип для логических атрибутов в сущностях базовых данных? - PullRequest
14 голосов
/ 20 июня 2009

Я использую Core Data программно (то есть не использую .xcdatamodel файлы модели данных) почти так же, как это показано в Учебном пособии по основным данным Apple . Поэтому моя проблема в том, что когда я пытаюсь добавить атрибут к сущности с типом NSBooleanAttributeType, он немного глючит. Когда я добавляю его в мой заголовочный файл подкласса NSManagedObject (в учебнике это будет Run.h) как

@property (retain) BOOL *booleanProperty;

компиляция завершается неудачно, говоря error: property 'booleanProperty' with 'retain' attribute must be of object type.

Кажется, что в некоторых местах в Какао используются 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 в моем пользовательском заголовке класса?

Ответы [ 8 ]

18 голосов
/ 14 октября 2010

Я бы не рекомендовал метод, предложенный Diederik Hoogenboom (я получил ошибку, хотя мой базовый атрибут данных был установлен как Boolean).

Стоит отметить, что хотя эта строка будет работать для пользовательского объекта, она не будет работать для подкласса NSManagedObject:

@property (nonatomic) BOOL booleanProperty;

Ваша собственность должна быть установлена ​​следующим образом:

@property (nonatomic, retain) NSNumber *booleanProperty;

Когда я копирую объявления методов для логического типа (используя технику, предложенную Джимом Коррейа), геттер и сеттер печатаются как:

NSNumber:-(NSNumber *)booleanProperty; 
-(void)setBooleanProperty:(NSNumber *)value;

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

-(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 *).

Наконец, вам нужно явно вызвать метод validate из любого контроллера представления / приложения, для которого вы устанавливаете объект:

    NSNumber *boolProp = [[[NSNumber alloc] initWithInt :0] autorelease];
    NSError *valError = nil;        
    if ([TheObject validateBooleanProperty:&boolProp error:&valError] == YES)
    {
        [TheObject setBooleanProperty :boolProp];   
    }       
18 голосов
/ 20 июня 2009

Попробуйте:

@property (nonatomic) BOOL booleanProperty;

Проблема заключалась в том, что вы использовали сохранение в определении свойства. Для этого у вас должно быть свойство для класса Objective-C (он должен уметь понимать метод 'retain'). BOOL - это не класс, а псевдоним для подписанного символа.

15 голосов
/ 28 марта 2012

В шапке

@property (nonatomic, retain) NSNumber *booleanProperty;

В реализации,

@dynamic booleanProperty;

Чтобы установить его в true ...

self.booleanProperty = [NSNumber numberWithBool:YES];

Чтобы установить его в ложь ...

self.booleanProperty = [NSNumber numberWithBool:NO];

Чтобы сравнить это с буквальным истинным логическим значением: ...

self.booleanProperty.boolValue == YES;

Чтобы сравнить это с буквальным ложным логическим значением: ...

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:

6 голосов
/ 01 июля 2009

Один из лучших способов создать правильные методы доступа в вашем подклассе NSManagedObject - вызвать контекстное меню атрибута или свойства в инструменте моделирования данных и выбрать одну из следующих команд:

  • Копировать объявления методов в буфер обмена
  • Копировать реализации метода в буфер обмена
  • Копирование объявлений метода Obj-C 2.0 в буфер обмена
  • Скопировать реализации метода Obj-C 2.0 в буфер обмена
4 голосов
/ 11 сентября 2011

Пусть Xcode 4.0 решит за вас. В Xcode: выберите Entity из вашего * .xcdatamodel вида файла.
Выберите «Редактор»> «Создать подкласс NSMagedObject ...» Xcode объявляет ваши логические объекты как тип NSNumber.

Edit: мне любопытно, что мотивирует для смягчения xcdatamodel? Кто-нибудь? * * 1004

3 голосов
/ 07 июля 2009

Атрибут типа Boolean в NSManagedObject имеет тип NSCFBoolean. Это частный подкласс NSNumber.

2 голосов
/ 21 июня 2009

Я не знаю, если это просто опечатка с вашей стороны, но это:

[NSArray arrayWithObjects:myEntityWithABooleanAttribute, myOtherEntity]

определенно не так. Последний параметр этого метода всегда должен быть равен нулю.

1 голос
/ 22 января 2011

Используйте NSNumber. В платформе CoreData нет бул.

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