I am working on an app that uses Core Data as its backend for managing SQLite records. I have everything working with strings and numbers, but have just tried adding BOOL fields and can't seem to get things to work.
In the .xcdatamodel, I have added a field to my object called isCurrentlyForSale
which is not Optional, not Transient, and not Indexed. The attribute's type is set to Boolean with default value NO.
When I created the class files from the data model, the boilerplate code added for this property in the .h header was:
@property (nonatomic, retain) NSNumber * isCurrentlyForSale;
along with the
@dynamic isCurrentlyForSale;
in the .m implementation file.
I've always worked with booleans as simple BOOLs. I've read that I could use NSNumber's numberWithBool
and boolValue
methods, but this seems like an aweful lot of extra code for something so simple.
Can the @property in the header be changed to a simple BOOL? If so is there anything to watch out for?
Thanks -John
Core Data is a framework that you use to manage the model layer objects in your application. It provides generalized and automated solutions to common tasks associated with object life cycle and object graph management, including persistence.
Core Data can use SQLite as its persistent store, but the framework itself is not a database. Core Data is not a database. Core Data is a framework for managing an object graph. An object graph is nothing more than a collection of interconnected objects.
As I mentioned earlier, the Core Data stack is the heart of Core Data. It's a collection of objects that make Core Data tick. The key objects of the stack are the managed object model, the persistent store coordinator, and one or more managed object contexts.
While Dave DeLong's answer is close, you can actually do this without having to change the name of the property.
You can change the property to return a BOOL
but you need to then write the accessor methods by hand and they are a bit different than what Dave has in his response.
First your @property
should be defined as:
@property (nonatomic, getter=isCurrentlyForSale) BOOL currentlyForSale;
Then in your implementation file, instead of declaring a @dynamic
property, create the accessors directly.
- (BOOL)isCurrentlyForSale
{
[self willAccessValueForKey:@"currentlyForSale"];
BOOL b = [[self primitiveValueForKey:@"currentlyForSale"] boolValue];
[self didAccessValueForKey:@"currentlyForSale"];
return b;
}
- (void)setCurrentlyForSale:(BOOL)b
{
[self willChangeValueForKey:@"currentlyForSale"];
[self setPrimitiveValue:[NSNumber numberWithBool:b] forKey:@"currentlyForSale"];
[self didChangeValueForKey:@"currentlyForSale"];
}
With these accessors your object will handle the boxing for you and you can access it as a primitive value. Also, a setter starting with setIs
is not a great idea, hence the removal of it in the example code.
Simple response: No, you cannot change the @property
declaration to return a BOOL
.
You can write some simple wrappers, though. I'd rename the attribute to currentlyForSale
(which means it generates currentlyForSale
and setCurrentlyForSale:
), and then write two wrappers:
- (BOOL) isCurrentlyForSale {
return [[self currentlyForSale] boolValue];
}
- (void) setIsCurrentlyForSale:(BOOL)forSale {
[self setCurrentlyForSale:[NSNumber numberWithBool:forSale]];
}
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