У меня есть приложение OS X на основе NSDocument
, которое вместо создания новых документов с пустой страницей показывает пользователю панель для выбора шаблона, как, например, Apple Pages.app.
Я сделал это, вручную создав новый экземпляр NSDocument
, когда пользователь запускает новый документ, и немедленно установив для него свойство, чтобы отразить, какой шаблон выбрал для него пользователь:
MyNSDocumentSubclass *newDoc = [sharedDocumentController makeUntitledDocumentOfType:fileType error:&err];
[newDoc setTemplate:templateChosenByUser]; // autosave doesn't care about this line
[sharedDocumentController addDocument:newDoc];
[newDoc makeWindowControllers];
[newDoc showWindows];
Это работает нормально, пока пользователь не решит перезагрузить компьютер или закрыть приложение без сохранения: когда функция автосохранения App Kit пытается восстановить прежнее состояние моего приложения при его следующем запуске, она не может сделать это для свойства пользовательского шаблона, потому что никогда не заметил, что состояние модели MyNSDocumentSubclass
изменилось, и в первую очередь не было автоматически сохранено весь документ. Вместо этого, вероятно, из соображений оптимизации производительности, просто создается новый экземпляр MyNSDocumentSubclass
, и выбор шаблона пользователя теряется.
Чтобы исправить это, я добавил
[newDoc updateChangeCount:NSChangeDone];
чтобы отразить шанс модели, представленный выбором шаблона пользователем. Теперь автосохранение срабатывает правильно и сохраняет документ до выключения компьютера или приложения. Единственный недостаток (и моя проблема, с которой я прошу здесь помощи) заключается в том, что это неправильный способ сделать: NSChangeDone
предназначен для отражения шанса на модель документа, инициированного пользователем. Таким образом, это приводит к тому, что «отредактированный» уже отображается в окне нового документа, и отображает панель сохранения для пользователя при закрытии окна. Однако выбор пользователем шаблона на самом деле не является изменением, которое следует считать «редактированием», поскольку оно тесно связано с созданием нового документа. К счастью, в примечаниях к выпуску OS X говорится именно об этой проблеме и предлагается решение:
Некоторые приложения используют
-updateChangeCount:
, чтобы заставитьNSDocument
автоматически сохранять изменения, которые не исходят непосредственно от пользователя. Например, при импорте неродного типа документа некоторые приложения создают новый документ с импортированным содержимым и вызывают -updateChangeCount:
, чтобы гарантировать автоматическое сохранение документа с этим содержимым. Многие приложения используют для этой целиNSChangeDone
. Однако, поскольку пользователь явно не вызывал это изменение, нежелательно превращать этот документ в черновик. Приложения должны использовать правильныйNSDocumentChangeType
— в данном случаеNSChangeReadOtherContents
— чтобы предотвратить преобразование в черновик. ИспользованиеNSChangeDiscardable
также предотвратит создание черновика.
К сожалению, [newDoc updateChangeCount:NSChangeReadOtherContents]
вообще не работает. Он, безусловно, подавляет «отредактировано» в заголовке окна, но в то же время не позволяет автосохранению выполнять свою работу при завершении работы приложения: документ не сохраняется автоматически и теряет значение своего свойства шаблона при следующем запуске.
Так что я могу сделать? Я хочу, чтобы мой только что созданный подкласс NSDocument
автоматически сохранял выбранный пользователем шаблон. В то же время он не должен показываться пользователю как уже отредактированный, хотя на самом деле он его только что создал.
Единственное, что я могу придумать, это попытаться сохранить свойство шаблона с помощью протокола NSWindowRestoration
, но это кажется совершенно неправильным. Кроме того, восстановление окна срабатывает слишком поздно в процессе повторного открытия документа. Другая идея, которая у меня была, состоит в том, чтобы создать несколько разных подклассов NSDocument
(отражаемых разными типами файлов с одним UTI) для каждого шаблона, который может выбрать пользователь, вместо использования свойства в моем подклассе NSDocument
, но тем не менее это кажется неправильным. Иначе я пропал. Спасибо за вашу помощь.