Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Core Data and BOOL setup

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

like image 661
John Valen Avatar asked May 17 '10 15:05

John Valen


People also ask

What is a Core Data set?

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.

Is SQLite a Core Data?

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.

What is a Core Data stack?

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.


2 Answers

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.

like image 89
Marcus S. Zarra Avatar answered Sep 29 '22 10:09

Marcus S. Zarra


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]];
}
like image 26
Dave DeLong Avatar answered Sep 29 '22 08:09

Dave DeLong