Куда вы помещаете код очистки для подклассов NSDocument?

У меня есть приложение на основе документов, и я выделил NSDocument подкласс и предоставил необходимые методы, но мой документ нуждается в некоторой обширной очистке (необходимо запускать внешние задачи и т. Д.). Где лучше всего это поставить? Я пробовал несколько разных методов, таких как:

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

Если я помещаю его в dealloc, иногда он вызывается, а иногда - нет (нажатие Command + Q, похоже, обходит освобождение моего документа), но обязательно, чтобы этот код вызывался без сбоя (если программа не завершается неожиданно).


person dreamlax    schedule 16.03.2009    source источник


Ответы (2)


Попросите каждый документ добавить себя в качестве наблюдателя в локальный центр уведомлений для NSApplicationWillTerminateNotification. В его методе уведомления вызовите его метод очистки (который также следует вызывать из dealloc или close).

person Peter Hosey    schedule 16.03.2009

Правильный ответ здесь не подходил для моего варианта использования, но вопрос подходит. Отсюда дополнительный ответ.

Мой вариант использования: закрытие документа (который может быть одним из нескольких открытых), но не закрытие приложения.

В этом случае (на момент написания и если я просто ищу не в том месте) документация не так полезна, как могла бы.

Я добавил canCloseDocumentWithDelegate:shouldCloseSelector:contextInfo: переопределение в свой подкласс NSDocument и вызвал в нем super. В документации не сказано, нужно ли вызывать super, но небольшой журнал показывает, что система предоставляет селектор и контекст. Этот метод вызывается непосредственно перед закрытием документа.

- (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];    
}

Полезное обсуждение этого метода есть в CocoaBuilder. Если у этого подхода есть недостатки или лучшие способы сделать это, прокомментируйте.

person Obliquely    schedule 17.12.2012
comment
Я не думаю, что это полностью правильно: вы должны выполнять очистку только в shouldCloseSelector, потому что shouldCloseSelector вызывается только в том случае, если документ готов к закрытию (например, успешно сохранен). Вызов этого метода canClose не означает, что документ действительно будет закрыт (например, при сохранении может произойти сбой). - person Joel; 02.02.2015