Почему при сохранении файлов в NSDocument создаются версии одного и того же файла со странными символами в имени?
-
21-12-2019 - |
Вопрос
Я работаю над приложением на основе NSDocument, типом документа которого является пакет пакетов, содержащий набор файлов.Я сохраняю это так:
- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError **)outError
{
if (!self.documentFileWrapper) {
NSFileWrapper *documentFileWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
[self setDocumentFileWrapper:documentFileWrapper];
}
NSFileWrapper *defaultWrapper = [self.documentFileWrapper.fileWrappers objectForKey:@"default"];
if (!defaultWrapper) {
defaultWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
[defaultWrapper setPreferredFilename:@"someFile.ext"];
[self.documentFileWrapper addFileWrapper:defaultWrapper];
}
[defaultWrapper addRegularFileWithContents: ... some computed content for the file ... preferredFilename:@"someFile.ext"];
return self.documentFileWrapper;
}
Другими словами, в бандле создайте папку «default» и сохраните в ней «someFile.ext» с каким-нибудь содержимым.
Теперь проблема.Когда я смотрю, что на самом деле сохранено на диске, я вижу это:
Каждый раз, когда я сохраняю файл, оболочка NSDocument создает некоторую версию ресурса.Мне не нужны версионные клоны, мне нужен только ванильный файл с последним содержимым.
Откуда берутся версионные ресурсы?Что тут происходит?Есть ли документ, который мне следует прочитать?
Решение
Хорошо, думаю, я понял это.Как оказалось, на самом деле это была не проблема с версиями.Похоже, вы просто каждый раз добавляли новый файл.Сначала несколько замечаний.
- Похоже, вы создаете не файл в пакете, а «каталог, содержащий файл» в пакете.Это то, что вы намеревались сделать?
- Кажется, что если каталог «по умолчанию» не существует, вы создаете и используете каталог «someFile.ext», а это означает, что в следующий раз будет создан новый каталог со странным префиксом.Однако на вашем скриншоте я вижу, что у вас уже есть каталог «по умолчанию», а это значит, что это не ваша проблема.
Теперь ваша актуальная проблема:в соответствии с эта документация, addRegularFileWithContents
создает новый файл с вашим предпочтительным именем файла, пока не каталог (defaultWrapper
) уже содержит файл с таким именем (по сути).Если он уже есть, создается новый файл с префиксом. addRegularFileWithContents
возвращает идентифицирующую строку, ссылающуюся на созданный NSFileWrapper (я думаю, это имя файла).
Итак, каждый раз, когда вы пытаетесь сохранить файл, он видит, что файл с таким именем уже существует, и создает новый с префиксом.Один из способов решения этой проблемы — сохранить возвращаемую NSString. addRegularFileWithContents
, затем, когда вы собираетесь сохранить, вы проверяете defaultWrapper
и удалите NSFileWrapper, связанный с сохраненной NSString, если она есть, а затем добавьте файл, как обычно.Я изменил ваш код следующим образом:
@interface TestDocument () // Relevant part of my test class. Note `wrapperFileName`.
@property (nonatomic, strong) NSFileWrapper *documentFileWrapper;
@property (nonatomic, strong) NSString *wrapperFileName;
@end
- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError **)outError
{
if (!self.documentFileWrapper) {
NSFileWrapper *documentFileWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
[self setDocumentFileWrapper:documentFileWrapper];
}
NSFileWrapper *defaultWrapper = [self.documentFileWrapper.fileWrappers objectForKey:@"default"];
if (!defaultWrapper) {
defaultWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
[defaultWrapper setPreferredFilename:@"default"];
[self.documentFileWrapper addFileWrapper:defaultWrapper];
} else if (self.wrapperFileName) {
[defaultWrapper removeFileWrapper:[[defaultWrapper fileWrappers] objectForKey:self.wrapperFileName]];
}
self.wrapperFileName = [defaultWrapper addRegularFileWithContents:[@"blah blah" dataUsingEncoding:NSUTF8StringEncoding] preferredFilename:@"someFile.txt"];
return self.documentFileWrapper;
}
- Я изменил
defaultWrapper
предпочитаемое имя файла — «по умолчанию», как я подозреваю, вы и предполагали. - Я добавил
if
блок, удаляющий ранее сохраненный файл, если он существовал. - Я сохранил имя нового файла NSFileWrapper для использования в следующий раз в #2.
После этих изменений программа продемонстрировала то поведение, которое, как мне кажется, вы ожидаете:один каталог, содержащий один файл, даже после многократного сохранения.Обратите внимание, что это было верно, даже когда preservesVersions
вернулся YES
.Я не уверен, где он хранит свои версии, но я их не видел.
Другие советы
Вы могли бы реализовать -WRITEFELEFELE ... так что он звонит прямо к -маритетурл: ... Реализуйте -маритетурл: ... так что он звонит -fileWrapperoftype: ... а затем пишет это на URL атомным образом
I.e.Вы бы взяли на себя ответственность за атомную экономию, сделав NSFileWrapper сделать это.Таким образом, обертка должна аккуратно тратить, где файлы действительно в конечном итоге.
Источник .