iosobjective-ccore-datamemory-managementuimanageddocument

Message sent to deallocated instance VERY WEIRD ERROR


I'm using Xcode 5.02 and iOS 7.04 and I've been searching long and hard to solve this annoying bug, and after many hours of debugging, I still cannot squash this bug.

So I'm using a UIManagedDocument Helper class in order to retrieve my data

+ (void)openDocument:(NSArray *)documentData {
NSString *documentName = documentData[0];
CompletionBlock completionBlock = documentData[1];

NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *documentsDirectory = [[fileManager URLsForDirectory:NSDocumentDirectory
                                                 inDomains:NSUserDomainMask] lastObject];
NSURL *url = [documentsDirectory URLByAppendingPathComponent:documentName];

UIManagedDocument *document = [[UIManagedDocument alloc] initWithFileURL:url];

void (^OnDocumentDidLoad)(BOOL) = ^(BOOL success) {
    completionBlock(document);
    preparingDocument = NO;
};

if(!preparingDocument){
    preparingDocument = YES;

    if(!([fileManager fileExistsAtPath:[url path]])){
        [document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForCreating
          completionHandler:OnDocumentDidLoad];
    } else if(document.documentState == UIDocumentStateClosed){
        [document openWithCompletionHandler:OnDocumentDidLoad];
    } else if (document.documentState == UIDocumentStateNormal) {
        OnDocumentDidLoad(YES);
    }
}  else {
    //Try till Document is Ready
    [self performSelector:@selector(openDocument:)
               withObject:documentData
               afterDelay:0.5];
}
}

In my view controller, I use this helper class in order to gain access to my ManagedObjectContext

- (void)updateContext{
[DocumentHelper openDocument:@[DOCUMENT_NAME, ^(UIManagedDocument *document) {
    self.managedObjectContext = document.managedObjectContext;
}]];
}

And this updateContext method gets called usually upon updating the CoreData, such as adding or deleting new items, however this method is also called in the (void)viewWillAppear method and in a notification block when the Application is in the Foreground (Using the Application Delegate)

Whenever I put the application into the background and reopen the application, the application crashes saying

*** -[UIManagedDocument _setInConflict:]: message sent to deallocated instance 0x1701b0ae0

I used malloc and the NSZombie Profile manager, but no matter what this bug is like a ticking time bomb. The error occurs upon a random number of times of closing and reopening the app.


Solution

  • I experienced the same problem today.

    * -[UIManagedDocument _setInConflict:]: message sent to deallocated instance 0x1701b0ae0

    This message indicates that your UIManagedDocument instance has been deallocated but is having a message sent to it. I solved the issue in my project by declaring the document variable as a file-level variable (outside of the method) so that it would not be too-hastily released, and only setting it to nil after I was done using it.

    EDIT to answer question: My app checks and updates from an iCloud document in the app delegate. In my AppDelegate.h file, I have this:

    @interface CSPAppDelegate : UIResponder <UIApplicationDelegate> {
        BOOL iCloudAvailable;
        NSMetadataQuery *_query;
        CSPICloudDocument *doc; // <<< declare document variable here instead of in method
    }
    

    The document is instantiated in the relevant method. The only real difference between your code and what I'm doing is where I've declared the variable. This was sufficient to solve the same error for me.