This post is for code nerds. We recently dealt with a very difficult problem so we hope by posting our solution here that we can save other developers some heartache.

While developing a new app we ran into a crash when trying to set a relationship on a core data NSManagedObject. The crash error message was:

-[NSCFNumber entity]: unrecognized selector sent to instance

Normally, this error message speaks to a memory management problem but try as we might we could find no memory management errors. It turned out to be a problem with some methods we added to our core data class via a Category.

XCode will automatically generate subclasses of NSManagedObject for the objects in your model. We like to add convenience and business logic methods in a Category that we attach to the class so that if we ever need to change the model and regenerate the class files that we don’t lose the extensions we’ve written.

In our example, we were saving different types of mathematical calculations. A top level object, SavedCalculation, contained relationships to optional child objects like SavedAmortization.

@interface SavedCalculation : NSManagedObject
{
}
@property (nonatomic, retain) NSDate * creationDate;
@property (nonatomic, retain) SavedAmortization * amortization;
@end

As a convenience method, we added the following Category method:

@implementation SavedCalculation (Extended)
- (BOOL) isAmortization {
return self.amortization != nil;
}

After that whenever we would try to assign a SavedAmortization to the SavedCalculation.amortization field our code would crash with the above error about an NSNumber. The “is” style of boolean property name clobbered the original definition:

@property (nonatomic, retain) SavedAmortization * amortization;

The internal code was assuming that -isAmortization would return a SavedAmortization* but when it returned a BOOL the code automatically wrapped it in an NSNumber. Later on when the code tried to get the -entity for the SavedAmortization, it caused the crash because the object was really an NSNumber instead of a SavedAmortization.

SOLUTION: We changed the name of the convenience method to -hasAmortization which doesn’t clobber the originally defined property and everything works very well.

Core Data and -[NSCFNumber entity]: unrecognized selector sent to instance

Leave a Reply

Your email address will not be published. Required fields are marked *