Подтвердить что ты не робот

Создать папку/каталог в Objective-C/cocoa

У меня есть этот код для создания папки/каталога в Objective-C/cocoa.

if(![fileManager fileExistsAtPath:directory isDirectory:&isDir])
        if(![fileManager createDirectoryAtPath:directory attributes:nil])
            NSLog(@"Error: Create folder failed %@", directory);

Он отлично работает, но я получил предупреждающее сообщение creatDirectoryAtPath:attributes is deprecated. Какой самый новый способ создания компоновщика каталогов в Cocoa/Objective-c?

решаемые

BOOL isDir;
NSFileManager *fileManager= [NSFileManager defaultManager]; 
if(![fileManager fileExistsAtPath:directory isDirectory:&isDir])
    if(![fileManager createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:NULL])
        NSLog(@"Error: Create folder failed %@", directory);
4b9b3361

Ответ 2

Ваше решение верно, хотя Apple содержит важную заметку в NSFileManager.h:

/* The following methods are of limited utility. Attempting to predicate behavior 
based on the current state of the filesystem or a particular file on the 
filesystem is encouraging odd behavior in the face of filesystem race conditions. 
It far better to attempt an operation (like loading a file or creating a 
directory) and handle the error gracefully than it is to try to figure out ahead 
of time whether the operation will succeed. */

- (BOOL)fileExistsAtPath:(NSString *)path;
- (BOOL)fileExistsAtPath:(NSString *)path isDirectory:(BOOL *)isDirectory;
- (BOOL)isReadableFileAtPath:(NSString *)path;
- (BOOL)isWritableFileAtPath:(NSString *)path;
- (BOOL)isExecutableFileAtPath:(NSString *)path;
- (BOOL)isDeletableFileAtPath:(NSString *)path;

По сути, если несколько потоков/процессов одновременно изменяют файловую систему, состояние может меняться между вызовом fileExistsAtPath:isDirectory: и вызовом createDirectoryAtPath:withIntermediateDirectories:, поэтому в этом контексте излишне и, возможно, опасно вызвать fileExistsAtPath:isDirectory:.

Для ваших нужд и в рамках ограниченного объема вашего вопроса это, вероятно, не будет проблемой, но следующее решение является более простым и дает меньше шансов на возникновение будущих проблем:

NSFileManager *fileManager= [NSFileManager defaultManager];
NSError *error = nil;
if(![fileManager createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:&error]) {
     // An error has occurred, do something to handle it
     NSLog(@"Failed to create directory \"%@\". Error: %@", directory, error);
}

Также обратите внимание на документацию Apple:

Возвращаемое значение

ДА, если каталог был создан, YES, если установлено createIntermediates и каталог уже существует), или НЕТ, если произошла ошибка.

Итак, установка createIntermediates в YES, которую вы уже выполняете, является де-факто проверкой того, существует ли каталог.

Ответ 3

Думаю, я бы добавил к этому и еще немного упомянул о документации по использованию метода + defaultManager:

В iOS и Mac OS X v 10.5 и более поздних версиях следует использовать [[NSFileManager alloc] init], а не singleton method defaultManager. Экземпляры NSFileManager считаются потокобезопасными при создании с помощью [[NSFileManager alloc] init].