Where do you put cleanup code for NSDocument sub-classes?
Asked Answered
C

2

7

I have a document-based application and I have sub-classed NSDocument and provided the required methods, but my document needs some extensive clean-up (needs to run external tasks etc). Where is the best place to put this? I have tried a few different methods such as:

  • close
  • close:
  • canCloseDocumentWithDelegate:shouldCloseSelector:contextInfo
  • dealloc

If I put it in dealloc, sometimes it gets called and other times it does not (pressing Command+Q seems to bypass my document's deallocation), but it is mandatory that this code gets called without failure (unless program unexpectedly terminates).

Crawley answered 16/3, 2009 at 4:20 Comment(0)
P
9

Have each document add itself as an observer in the local notification center for NSApplicationWillTerminateNotification. In its notification method, call its clean-up method (which you should also call from dealloc or close).

Peek answered 16/3, 2009 at 4:58 Comment(0)
G
8

The correct answer here didn't fit my use case, but the question does. Hence the extra answer.

My use case: closing a document (which may be one of several that are open) but not closing the application.

In this case (at time of writing and unless I'm just looking in the wrong place) the documentation is not as helpful as it could be.

I added a canCloseDocumentWithDelegate:shouldCloseSelector:contextInfo: override in my NSDocument subclass and called super within it. The documentation doesn't say whether you must call super, but a bit of logging shows that the system is providing a selector and a context. This method is called just before the document is closed.

- (void) canCloseDocumentWithDelegate:(id)delegate shouldCloseSelector:(SEL)shouldCloseSelector contextInfo:(void *)contextInfo;
{
    if ([self pdfController])
    {
        [[[self pdfController] window] close];
        [self setPdfController: nil];
    }

    [super canCloseDocumentWithDelegate:delegate shouldCloseSelector: shouldCloseSelector contextInfo: contextInfo];    
}

There is some useful discussion of this method on CocoaBuilder. If there's downsides to this approach or better ways of doing this, please comment.

Gretagretal answered 17/12, 2012 at 18:41 Comment(1)
I don't think this is entirely correct: you should only do the cleanup in the shouldCloseSelector because the shouldCloseSelector only gets called if the document is ready to be closed (e.g. successfully saved). This canClose method getting called does not indicate that the document will actually get closed (e.g. the save could fail).Maples

© 2022 - 2024 — McMap. All rights reserved.