Tobi Weißhaar
Tobi Weißhaar

Reputation: 1677

Core Data - initWithEntity causes unrecognized selector sent to instance

I want to use core data to persist some entities like events.

Therefore I use the classes DSManagedObject and Event

The class DSManagedObject extends NSManagedObject and has general methods that all entities can use. The class Event extends DSManagedObject.

The following code is the DSManagedObject.h and .m. The relevant code in the .m is just the getContext-method.

@interface DSManagedObject : NSManagedObject

+ (NSManagedObjectContext *)getContext;
- (NSArray*)getEntitiesForName:(NSString*)_entityName context:(NSManagedObjectContext*)_context;
- (Event*)getEntityForName:(NSString*)_entityName forEventId:(NSInteger)_eventId context:(NSManagedObjectContext*)_context;
- (bool)deleteEntityForName:(NSString*)_entityName forEventId:(NSInteger)_eventId context:(NSManagedObjectContext*)_context;

@end


@implementation DSManagedObject

+ (NSManagedObjectContext *)getContext {

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],NSMigratePersistentStoresAutomaticallyOption,
                             [NSNumber numberWithBool:YES],
                             NSInferMappingModelAutomaticallyOption, nil];


    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
    NSURL *storeUrl = [NSURL fileURLWithPath:[basePath stringByAppendingFormat:@"DesertStorm.sqlite"]];
    NSPersistentStoreCoordinator *persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:nil]];
    NSError *error = nil;

    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
        NSLog(@"error loading persistent store..");
        [[NSFileManager defaultManager] removeItemAtPath:storeUrl.path error:nil];
        if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }



    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
    [context setPersistentStoreCoordinator:persistentStoreCoordinator];

    return context;


}

Now in the class Event I want to call initWithEntity but then the error [Event managedObjectModel] unrecognized selector sent to instance occurs. What's the reason ? :(

@interface Event : DSManagedObject

@property (assign)              NSInteger   eventId;

@end


@implementation Event

@dynamic eventId;

- (id)init {

    NSEntityDescription *entity = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:[DSManagedObject getContext]];
    self = [self initWithEntity:entity insertIntoManagedObjectContext:[DSManagedObject getContext]];  // error occurs
    self = [super init];
    if (self) {

    }
    return self;
}

...

@end

I'm new in using core data so show understanding ;) Thanks for help

PS: If you wonder why I override the init-method...complex reason^^

Upvotes: 2

Views: 2560

Answers (2)

Tobi Weißhaar
Tobi Weißhaar

Reputation: 1677

I solved the problem in the init-method. I still override the method (I know I shouldnt but...anyway)

Here's the code

- (id)init {
    return [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:[DSManagedObject getContext]];
}

this will return a NSManagedObject and no errors occur :)

Upvotes: 0

Lorenzo B
Lorenzo B

Reputation: 33428

From Core Data doc:

In a typical Cocoa class, you usually override the designated initializer (often the init method). In a subclass of NSManagedObject, there are three different ways you can customize initialization —by overriding initWithEntity:insertIntoManagedObjectContext:, awakeFromInsert, or awakeFromFetch. You should not override init. You are discouraged from overriding initWithEntity:insertIntoManagedObjectContext: as state changes made in this method may not be properly integrated with undo and redo. The two other methods, awakeFromInsert and awakeFromFetch, allow you to differentiate between two different situations:

So the soultions are to override initWithEntity:insertIntoManagedObjectContext: or take advantage of awakeFromInsert or awakeFromFecth. If you want, ovveride the former since is called after you invoke initWithEntity:insertIntoManagedObjectContext: or insertNewObjectForEntityForName:inManagedObjectContext:.

Is there a particular goal that you want to achieve?

edit

Try to override initWithEntity:insertIntoManagedObjectContext: instead of init

- (id)initWithEntity:(NSEntityDescription*)entity insertIntoManagedObjectContext:(NSManagedObjectContext*)context    
{    
    self = [super initWithEntity:entity insertIntoManagedObjectContext:context];
    if (self != nil) {

        // Perform additional initialization.

    }

    return self;    
}

The method is the designated initializer for NSManagedObject. You must not initialize a managed object simply by sending it init. See NSManagedObject class for further info.

Upvotes: 5

Related Questions