1
votes

I have a subclassed NSManagedObject class:

@interface MapStateDB : NSManagedObject

@end

Now I want to make a subclass of MapStateDB class:

.h

@interface MapState : MapStateDB

@property (weak, nonatomic) id <MapStateDelegate> delegate;

@end

.m

@implementation MapState

@synthesize delegate = _delegate;

@end

Except when I try to create a MapState object, it fails:

MapState *mapState = [MapState MR_createEntityInContext:context];

DLog(@"mapState: %@", mapState);

output:

DEBUG | -[LoginViewController testStuff] | mapState: (null)

I can create a `MapStateDB" object just fine:

MapStateDB *mapStateDB = [MapStateDB MR_createEntityInContext:context];
DLog(@"mapStateDB: %@", mapStateDB);

output:

DEBUG | -[LoginViewController testStuff] | mapStateDB: <MapStateDB: 0x7d432d00> (entity: MapStateDB; id: 0x7d424640 <x-coredata:///MapStateDB/tF842754F-4044-44E5-A9D5-118389ABF4AA2>

The original intent is to provide a delegate to a NSManagedObject and was suggested in another question to subclass my NSManagedObject: NSManagedObject with Category and Delegate

Any ideas why the subclassed MapState object isn't being created?

EDIT:

I replaced the Magical Record method [MR_createEntityInContext:] with the Objective-C standard [insertNewObjectForEntityForName:inManagedObjectContext:]:

MapState *mapState2 = [NSEntityDescription insertNewObjectForEntityForName:@"MapState" inManagedObjectContext:context];
DLog(@"mapState2: %@", mapState2);

output:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an entity named 'MapState' in this model.'

So Magical Record was catching the error and returning nil. So I guess @Rickster's question is pointing to the issue, my Core Data model has no idea what MapState is.

Could I make a transient property for the delegate? OR should I just use a wrapper class?

Is it possible to get a NSManagedObject with a delegate property?

EDIT 2:

I tried changing the MapStateDB entities' class to FooMapState:

enter image description here

I used Xcode to create the subclassed NSManagedObject and it created FooMapState.h/.m files (instead of just MapState.h/.m files):

@interface FooMapState : NSManagedObject

@end

The FooMapState and MapState are identical, just with different names. They are both subclassed NSManagedObject which makes creating a delegate difficult (back to the original question I posted).

1
Is there a corresponding sub-entity for the subclass in your xcdatamodel? - rickster
Are you asking if there is a MapState in the data model? No, there is not. If I did, I believe I would run into the same issue when trying to created a delegate property. - Padin215
Since you have the source code to Magical Record, now would be a good time to step through MR_createEntityInContext (and whatever methods it calls) to see what's causing it to return nil. - Tom Harrington
I replaced the Magical Record method with the default creating method: [NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:] and I get the error "+entityForName: could not locate an entity named 'MapState' in this model". Will update question. - Padin215
You won't really be able to do what you're trying to do. When creating a new entity, Core Data will always create a class of the type specified in the model. There's no mechanism to instantiate an entity and specify the class name it should be created as. You can play around with entity inheritance, but it's not good to abuse the feature just to fake inheritance. - Avi

1 Answers

1
votes

You're having problems because you're trying to create an instance of the entity MapState, but there is no such entity in your data model-- the entity name is MapStateDB.

It's OK to have the MapState subclass, but in order for creating instances to work, you need to set the right class name for the entity in your data model. So on the MapStateDB entity, set the class name to MapState (You can type any class name there, really). Then when you create a new instance of the MapStateDB entity, you'll get an instance of the MapState class.