2009-06-20 2 views
14

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

@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 в свой собственный заголовок класса?

ответ

18

Try:

@property (nonatomic) BOOL booleanProperty; 

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

+0

также стоит отметить, что это «BOOL booleanProperty», без *. * - только для указателей, включая указатели объектов. –

+1

См. [Этот ответ] (http://stackoverflow.com/a/3934284/164989) для более подходящего решения. – opsidao

+0

Этот ответ следует удалить, поскольку он просто неверен. –

2

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

[NSArray arrayWithObjects:myEntityWithABooleanAttribute, myOtherEntity] 

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

+0

Спасибо, что указали это! Это была опечатка. –

6

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

  • Copy Method Объявления в буфер
  • Копировать Метод Реализации в буфер обмена
  • Копировать Obj-C Метод 2.0 Declarations в буфер
  • Копировать Obj-C Метод 2.0 Реализации в буфер
3

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

18

Я бы не рекомендовал метод, предложенный 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 *).

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

NSNumber *boolProp = [[[NSNumber alloc] initWithInt :0] autorelease]; 
    NSError *valError = nil;   
    if ([TheObject validateBooleanProperty:&boolProp error:&valError] == YES) 
    { 
     [TheObject setBooleanProperty :boolProp]; 
    }  
1

Используйте NSNumber. В структуре CoreData не существует bool.

4

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

Редактировать: Мне любопытно, что мотивация для смягчения xcdatamodel? Кто угодно?

15

В заголовке,

@property (nonatomic, retain) NSNumber *booleanProperty; 

В реализации

@dynamic booleanProperty; 

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

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:

+1

Или используйте сокращенное обозначение, self.booleanProperty = @ (NO); – pojo

+0

То, что мне нужно. Спасибо, что выбрали лишнюю милю. (Y), –

Смежные вопросы