Question

I am wondering how I can prevent a crash when trying to close UIDoc twice. I tried to make sure in my code that you (theoretically) can not close a UIDocument twice. However, it still happens sometimes and I don't know why. If it does, the app crashes:

2012-07-06 15:24:34.470 Meernotes[11620:707] ... doc state:Normal
2012-07-06 15:24:34.472 Meernotes[11620:707] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'closeWithCompletionHandler called while document is already closing'
*** First throw call stack:
(0x3720e88f 0x34f13259 0x3720e789 0x3720e7ab 0x312681d1 0xd19db 0x96f7f 0x9593f 0xacb8f 0x30f0cd23 0x37a7f933 0x371e2a33 0x371e2699 0x371e126f 0x371644a5 0x3716436d 0x33923439 0x30f10cd5 0x94fdd 0x94f78)
terminate called throwing an exception(lldb) 

I tried to prevent the crash as follows, but it has no effect whatsoever (i.e. it will still crash):

-(void)closeDoc {

    UIDocumentState state = _selectedDocument.documentState;

    NSMutableArray * states = [NSMutableArray array];
    if (state == 0) {
        [states addObject:@"Normal"];
    }
    if (state & UIDocumentStateClosed) {
        [states addObject:@"Closed"];
    }
    if (state & UIDocumentStateInConflict) {
        [states addObject:@"In conflict"];
    }
    if (state & UIDocumentStateSavingError) {
        [states addObject:@"Saving error"];
    }
    if (state & UIDocumentStateEditingDisabled) {
        [states addObject:@"Editing disabled"];
    }
    NSLog(@"... doc state: %@", [states componentsJoinedByString:@", "]);

    if (_selectedDocument.documentState & UIDocumentStateClosed) return;

    [_selectedDocument closeWithCompletionHandler:^(BOOL success) {

        NSLog(@"Closed document.");
        // Check status
        if (!success) {
            NSLog(@"Failed to close %@", _selectedDocument.fileURL);
        } else {
            _selectedDocument = nil;
        }

    }];             
}
Was it helpful?

Solution

It looks like UIDocument doesn't store the closing state, only normal and closed, so you'll have to do it yourself.

Add this to your class variables:

BOOL _documentClosing;

And add its use in your closeDoc method:

-(void)closeDoc {

    if (_docClosing || (_selectedDocument.documentState & UIDocumentClosed) != 0)
        return;
    _docClosing = YES;

    [_selectedDocument closeWithCompletionHandler:^(BOOL success) {

        NSLog(@"Closed document.");
        // Check status
        if (!success) {
            NSLog(@"Failed to close %@", _selectedDocument.fileURL);
        } else {
            _selectedDocument = nil;
            _docClosing = NO;
        }

    }];             
}

OTHER TIPS

It's very important to know that each UIDocument object can only be opened and closed once. I had a lot of odd problems with UIDocuments before realizing this, both in the cloud and with local files. When you close a document set its pointer to nil, so you can't close it again. If you need to access the same file again later, create a new UIDocument with the same fileURL.

The error message you show above is one that appears when you try to re-use a document.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top