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);
ソリューションは正しいですが、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's 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が設定されていてディレクトリが既に存在する場合はYES)、エラーが発生した場合はNO。
したがって、createIntermediates
をYES
に設定することは、既に行っていますが、ディレクトリが既に存在するかどうかの事実上のチェックです。
私はこれに追加し、+ defaultManagerメソッドの使用に関するドキュメントからもう少し言及すると思いました:
iOSおよびMac OS X v 10.5以降では、シングルトンメソッドdefaultManagerではなく[[NSFileManager alloc] init]の使用を検討する必要があります。NSFileManagerのインスタンスは、[[NSFileManager alloc] init] 。
NSFileManager
メソッドを使用することをお勧めします。
createDirectoryAtURL:withIntermediateDirectories:attributes:error:
パス文字列ではなくURLで機能します。