I am using Core Data programmatically (i.e. not using .xcdatamodel
data model files) in much the same manner as depicted in Apple's Core Data Utility Tutorial. So my problem is that when I try to add an attribute to an entity with the type NSBooleanAttributeType
, it gets a bit buggy. When I add it to my NSManagedObject
subclass header file (in the tutorial, that would be Run.h
) as
@property (retain) BOOL *booleanProperty;
compiling fails, saying error: property 'booleanProperty' with 'retain' attribute must be of object type
.
It seems like some places in Cocoa use NSNumber
objects to represent booleans, so I tried setting it to
@property (retain) NSNumber *booleanProperty;
instead. However, this evokes the following runtime errors:
*** -[NSAttributeDescription _setManagedObjectModel:]: unrecognized selector sent to instance 0x101b470
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSAttributeDescription _setManagedObjectModel:]: unrecognized selector sent to instance 0x101b470'
Using GDB, I am able to trace this back to the line in my source code where I add my entity to the managed object model:
[DVManagedObjectModel setEntities:[NSArray arrayWithObjects:myEntityWithABooleanAttribute, myOtherEntity]];
So my question is this: what type should I set booleanProperty to in my custom class header?
You can think of attributes as the columns of a table in a database. Attributes store the values of a Core Data record. There are several types of attributes, such as String, Date, Integer, Float, and Boolean.
Core Data provides different attributes, including those common for all databases, such as Date or Decimal type, and non-standard attributes handled with Transformable type. It also provides Transient and Derived attributes so apps can derive one piece of data from the other.
An entity describes an object, including its name, attributes, and relationships.
Try:
@property (nonatomic) BOOL booleanProperty;
The problem was that you used the retain in the property definition. For that you must have a property for an Objective-C class (it should be able to understand the 'retain' method). BOOL is not a class but an alias for signed char.
I wouldn't recommend the method suggested by Diederik Hoogenboom (i got an error even though my core data attribute was set as Boolean).
It's worth pointing out that although this line will work for a custom object, it will not work for a subclass of NSManagedObject:
@property (nonatomic) BOOL booleanProperty;
Your property should be set as this:
@property (nonatomic, retain) NSNumber *booleanProperty;
When i copy the method declarations for a Boolean type (using the technique suggested by Jim Correia), the getter and setter are typed as:
NSNumber:-(NSNumber *)booleanProperty;
-(void)setBooleanProperty:(NSNumber *)value;
...this is what a Boolean property in core data is set as, and you need to validate your property with something like this:
-(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
…remember to include the validateBooleanProperty declaration in the header file. The setter and getter methods store and retrieve your property using -(id)primitiveValueForKey:(NSString *)key.
Finally you need to explicitly call the validate method from whatever view controller / app delegate you're setting the object from:
NSNumber *boolProp = [[[NSNumber alloc] initWithInt :0] autorelease];
NSError *valError = nil;
if ([TheObject validateBooleanProperty:&boolProp error:&valError] == YES)
{
[TheObject setBooleanProperty :boolProp];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With