Long time lurker, first time to post.

I have a iPhone 3.0 application that is using core data in an NSOperation to perform some updates. It is using it's own NSManagedObjectContext connected to a common (with the main thread) persistent store coordinator. Everything works great until the NSOperation ends and is releasing the managed object context. I get an EXC_BAD_ACCESS on the operation thread. Here is the trace:

#0      0x91a3c688 in objc_msgSend
#1 0x0036c854 in -[_PFManagedObjectReferenceQueue _processReferenceQueue:] #2 0x003a7c40 in -[NSManagedObjectContext(_NSInternalAdditions) _dispose:]
#3      0x0040c92d in _deallocateContextBackgroundThread
#4      0x0035f41c in minion_duties2
#5      0x96777155 in _pthread_start
#6      0x96777012 in thread_start

At first I had assumed a simple memory management problem. The MOC is alloc'd by method call from the main method and released in the dealloc method of the operation. New objects are being inserted into this MOC & saved (and the main thread MOC being merged) before the dealloc. One clue is that if no new objects are added, it does not cause the crash above. So, my guess is that something bad is happening to the managed objects and they are being over-released? During the creation of managed objects, at certain intervals a local autorelease pool is created, then objects saved, then the pool is drained. Yet, even if the managed objects are released, it does not seem that the context should crash on it's own release?

I have spent some time searching on google and found another case of this occurring. Yet, the solution was to set the MOC to retain the managed objects. This did not work in my case. I have also tried forcing the MOC to processPendingChanges and also reseting prior to the release to see if that would help, no luck. Of course, eliminating the release of the MOC in the dealloc method did keep it from crashing (and everything works great), but this then becomes a leak.

Anyone have a similar problem or an idea on how to further figure this out?

Here is a cut of the code showing the relevant sections.

.h

#import <Foundation/Foundation.h>
@interface GRUpdateDatabaseOperation : NSOperation
{
        id                                              delegate;
        NSManagedObjectContext                          *managedObjectContext;
        NSPersistentStoreCoordinator                    
*persistentStoreCoordinator;
}

@property (nonatomic, assign) id delegate;
@property (nonatomic, readonly) NSManagedObjectContext *managedObjectContext; @property (nonatomic, retain) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (id)initWithDelegate:(id)aDelegate persistentStoreCoordinator: (NSPersistentStoreCoordinator *)aPersistentStoreCoordinator;

@end

.m
#import "GRUpdateDatabaseOperation.h"
@implementation GRUpdateDatabaseOperation

@synthesize delegate;
@synthesize persistentStoreCoordinator;

- (id)initWithDelegate:(id)aDelegate persistentStoreCoordinator: (NSPersistentStoreCoordinator *)aPersistentStoreCoordinator
{
        if (!(self = [super init])) {
                return nil;
        }
        self.delegate:aDelegate;
        self.persistentStoreCoordinator = aPersistentStoreCoordinator;
        return self;
}

- (void) dealloc
{
        [managedObjectContext release]; // problem with crash is here!
        [persistentStoreCoordinator release];
        [super dealloc];
}

#pragma mark Core Data Stuff

- (NSManagedObjectContext *) managedObjectContext {
        
    if (managedObjectContext != nil) {
        return managedObjectContext;
    }
        
NSPersistentStoreCoordinator *coordinator = self.persistentStoreCoordinator;
    if (coordinator != nil) {
        managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator: coordinator]; [managedObjectContext setUndoManager:nil]; // speeds up performance for no undo
    }
                        
    return managedObjectContext;
}

- (void)saveAction:(id)sender {
        
    NSError *error;
    if (![[self managedObjectContext] save:&error]) {
                // Handle error
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
                exit(-1);  // Fail
    }
}

-(void) contextDidSave:(NSNotification *)notification
{       
        if ([self.delegate respondsToSelector:@selector(mergeChanges:)]) {
                DLog(@"Sending off mergeChanges to main thread");
[self.delegate performSelectorOnMainThread:@selector(mergeChanges:) withObject:notification waitUntilDone:YES];
        }
}

#pragma mark Main

- (void)main
{       
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext];

.... BUNCH OF CODE HERE TO CREATE CREATE AND INSERT NEW OBJECTS INTO MOC ...
                
        [self saveAction:nil];
        
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext];

}

@end
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to