Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

tutiplain

macrumors member
Original poster
Feb 4, 2011
95
0
Hi everyone,

I am currently trying to learn how to use the Core Data framework. There seem to be many tasks, like initializing the persistent store and creating the object context, which are repetitive. I thought I'd try to write a wrapper class that does this for me. Now, when debugging, all these objects seem to have values, but whenever I try to do anything with the context object in particular, the application fails with either an exception or a "EXC_BAD_ACCESS" error.

My wrapper class has three properties, called "context", "coordinator" and "model" of types NSManagedObjectContext, NSPersistentStoreCoordinator and NSManagedObjectModel, accordingly.

My init method is like this:

Code:
-(id)initWithDatabase:(NSString *)db_path andModelNameInResources:(NSString *)modelName withExtension:(NSString *)ext
{
 
    NSManagedObjectModel* _model;
    NSManagedObjectContext* _context;
    NSPersistentStoreCoordinator* _coord;
    
    //begin by initializing the ManagedObjectModel
    NSURL* modelURL = [[NSBundle mainBundle] URLForResource:modelName withExtension:ext];
    _model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
 
    
    //Persistent Store Coordinator setup
    //- URL for app documents folder
    NSArray* docsDirArray = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
    NSURL *docsDir = [docsDirArray lastObject];
    NSURL* dbPathURL = [docsDir URLByAppendingPathComponent:db_path];
    _coord =[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_model];
    NSError * error;
    [_coord addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:dbPathURL options:nil error:&error];
    
    
    //finally, set up the object context
    _context = [[NSManagedObjectContext alloc] init];
    [_context setPersistentStoreCoordinator:self.coordinator];
    
    
    //assign to objects properties
    self.model = _model;
    self.context =_context;
    self.coordinator =_coord;
    
    return self;    
}

I have another method in this class to get me a NSEntityDescription:

Code:
-(NSEntityDescription *)descriptionForEntityName:(NSString *)entityName
{
    NSManagedObjectModel *_model = [self.coordinator managedObjectModel];
    NSArray * dict = [_model entities];
    NSEntityDescription *descr;
    int x;
    for (x=0;x<=[dict count]-1;x++) 
    {
        NSEntityDescription *tempDescr = [dict objectAtIndex:x];
        if ([tempDescr name] == entityName)
        {
            descr = tempDescr;
        }
    }
    //NSEntityDescription *descr = [NSEntityDescription entityForName:entityName inManagedObjectContext:_context];
    return descr;
    
}

Notice the commented line before return. Uncommenting it results in a "'+entityForName: could not locate an NSManagedObjectModel for entity name " message. If I let this line as a comment then attempt to use the returned NSEntityDescription to create an NSManagedObject like this:

Code:
  NSManagedObject* newTask = [[NSManagedObject alloc] initWithEntity:tareaDescription insertIntoManagedObjectContext:context];

The application halts with EXC_BAD_ACCESS. The problem seems to be an uninitialized or corrupted managed object context. Am I doing anything wrong in this initialization method? I've already verified the values of the parameters I am passsing into each method, and they are correct. The .sqlite file is created in the Apps Documents folder, and by the end of the initialization method, debugger shows me that all three properties have a value. Please help!
 
Last edited:
I've read through everything by the first thing I notice is that in initWithDatabase: you use self.coordinator before self.coordinator has been assigned.

Instead of:
Code:
[_context setPersistentStoreCoordinator:self.coordinator];
I think you want this:
Code:
[_context setPersistentStoreCoordinator:_coord];
 
Hi again, thanks for your reply. You're right. I missed that part. I made the fix you suggested. The "+entityForName: could not locate an NSManagedObjectModel for entity name " message is gone. However, when I do this:

Code:
-(void)create_mo
{
    [txtDescription resignFirstResponder];
    
    CoreDataLayer *dl = [[CoreDataLayer alloc] initWithDatabase:@"My_DB.sqlite" andModelNameInResources:@"My_model" withExtension:@"momd"];
      
    //NSManagedObjectContext* context = dl.context;
   
    if (self.action ==@"new") 
    {
        
        
        NSEntityDescription* moDescription =[dl descriptionForEntityName:@"MyTable"];
        NSManagedObject* newMO = [[NSManagedObject alloc] initWithEntity:moDescription insertIntoManagedObjectContext:dl.context];

     //other code

    }

where CoreDataLayer is my wrapper class.

The app halts on the initWithEntity:insertIntoManagedObjectContext method, and a green line appears below it in XCODE with "EXC_BAD_ACCESS". Could I still be missing something? This one doesn't even give me a message I can look up on google or anything.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.