views:

692

answers:

2

I'm getting the above error when the following runs in the iphone simulator (3.0 OS):

@interface Routine : NSManagedObject {

}

@property (nonatomic) BOOL active;

@implementation Routine
@dynamic active
@end

As you can see, I'm subclassing NSManagedObject because I'm using Core Data. In my data model, "active" is an option attribute of type Boolean.

What am I doing wrong here?

Thanks!

+8  A: 

Everything that comes out of CD is an object, not a scaler. So, changer your code to:

@interface Routine : NSManagedObject {

}

@property (nonatomic) NSNumber * active;

@implementation Routine
@dynamic active
@end

If you want you can add a convenience accessor to deal with it as a scalar:

- (BOOL) activeScalar {
  return self.active.boolValue;
}

- (void) setActiveScalar:(BOOL)active_ {
  self.active = [NSNumber numberWithBoolValue:active_];
}

Finally, if you cntrl-click on a property in the model editor it will bring up an enormous contextual menu, including options to copy the appropriate declarations and definitions into your paste board, so you don't have to write them yourself.

Louis Gerbarg
Awesome, that worked. Thank you!
higginbotham
Small mistake:Change to: - (void) setActiveScalar:(BOOL)active_ { self.active = [NSNumber numberWithBool:active_];}
benvolioT
A: 

For what it's worth, I found the docs provide a slightly different solution to scalars. Generally you're discouraged from using scalars instead of objects, but if you do then http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CoreData/Articles/cdNSAttributes.html explains how to do it. You use the "primitiveName" and "setPrimitiveName" to access automatically generated accessors that put your scalar into an object (e.g. NSNumber). Then create a scalar @property and write accessors for your property that use the primitives.

This seems expensive in that under the hood CoreData is storing your attribute as a scalar in the peristent store and converting it to an object to expose it as a primitive. So when you implement setName, as I read the docs and sample code, your value is placed in an object and then the scalar is extracted again in the setPrimitiveName automatic implementation. Seems like unnecessary marshaling back and forth for each get or set.

dk