0

I'm working with Core Data for ages. Currently I would like to learn more about UIManagedDocument. I've done several sample projects to learn more about it. Finally, I'm good to transfer this mechanism to the real projects. In the existing project, I'm currently implementing the Core Data, so I created the Data Model(with the same name as app). I've generated a class for a entity, then I've created category that has a simple method for adding objects to the database. Finally I created the singleton for the UIManagedDocument, for now it looks like this:

+ (MDManagedDocument *)sharedDocument {
    static dispatch_once_t dispatchOncePredicate;
    __strong static MDManagedDocument *md = nil;
    dispatch_once(&dispatchOncePredicate, ^{
        md = [[MDManagedDocument alloc] init];
    });
    return md;
}

- (id)init {
    self = [super init];
    if(self) {
        [self setManagedDocument:[[UIManagedDocument alloc] initWithFileURL:[[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent:@"ThisIsDatabase"]]];
        [[self managedDocument] setPersistentStoreOptions:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]];        
    }
    return self;
}

- (void)prepareManagedDocument {
    if (![[NSFileManager defaultManager] fileExistsAtPath:[[[self managedDocument] fileURL] path]]) {
        [[self managedDocument] saveToURL:[[self managedDocument] fileURL] forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
            if (success) {
                NSLog(@"Managed document was created.");
            } else {
                NSLog(@"Error occured while creating managed document.");
            }
        }];
    } else if([[self managedDocument] documentState] == UIDocumentStateClosed) {
        [[self managedDocument] openWithCompletionHandler:^(BOOL success) {
            if (success) {
                NSLog(@"Managed document was opened.");
            } else {
                NSLog(@"Error occured while opening managed document.");
            }
        }];
    } else if([[self managedDocument] documentState] == UIDocumentStateNormal) {
        NSLog(@"Managed document is opened and prepared for editing and/or reading.");
    }
}

After I'm instantiating shared instance and calling prepareManagedDocument method it crashes with this message:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString _cfurl]: unrecognized selector sent to instance 0xb3774b0'

Interesting thing is that it only crashes at the first run, but because of this crash it won't create a persistent storage, so it won't be able to write to the document etc. I have a project which is working with this code, and don't throw any exceptions, hence it is creating persistent store and I'm able to write to this document.

Where I'm wrong?

Thanks in advance!

Anatoliy Gatt
  • 2,501
  • 3
  • 26
  • 42
  • 2
    It seems you have a premature deallocation problem, and an NSString is filling the void where the object that would respond to that internal message would be. Turn zombies on, and malloc_stack debugging. – CodaFi Mar 27 '13 at 19:27
  • @CodaFi I enable both of them + I profiled my app with the help of Zombies Trace in Instruments, doesn't get any helpful info. By the way, in the second run when its trying to open a documents it logs the error message that I've implemented in the block that handles opening of the document. – Anatoliy Gatt Mar 27 '13 at 19:40
  • @CodaFi let me try to run it on the device. – Anatoliy Gatt Mar 27 '13 at 19:43
  • Try setting an "all exceptions" breakpoint. Then the debugger will step in when the exception is thrown, and you'll at least have a better idea of what's causing it. – Tom Harrington Mar 27 '13 at 19:47
  • @TomHarrington That was the first thing I've done. In the Debug Navigator there is no my sources that are causing the crash, so it is something internal, more precisely it is a Thread 9(just to be precise), UIDocument File Access, and then I see just an assembly code. – Anatoliy Gatt Mar 27 '13 at 19:50
  • 1
    Even if it doesn't show your code, the backtrace is often useful. – Tom Harrington Mar 27 '13 at 19:52
  • @TomHarrington #1 0x31790e06 in -[NSObject(NSObject) doesNotRecognizeSelector:] () That is what I'm getting as well in the same place where the crash occurs. But it's not much helpful to me right now. – Anatoliy Gatt Mar 27 '13 at 19:53
  • That's not a backtrace. I'm talking about the full stack trace from whatever tried to call this method up to where the exception occurred. – Tom Harrington Mar 27 '13 at 19:58
  • @TomHarrington [[self managedDocument] saveToURL:[[self managedDocument] fileURL] forSaveOperation:UIDocumentSaveForCreating completionHandler: - that is were the exception is thrown from my code. Let me check about the full stack. – Anatoliy Gatt Mar 27 '13 at 20:07

1 Answers1

0

Issue solved! I had a category that extends NSURL, and has only one method baseURL, after I remove this category or rename the method everything works fine.

Anatoliy Gatt
  • 2,501
  • 3
  • 26
  • 42