2

これら2つの再帰的な方法を使用して、特定のフォルダー内のファイルとディレクトリのパスを見つけています

- (NSMutableArray *)getFilePathsFromDirectory:(NSString *)directory{
NSMutableArray *contents = [[NSMutableArray alloc] init];
NSArray *arr = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directory error:nil];
for (NSString *file in arr) {
    BOOL isDir;
    [[NSFileManager defaultManager] fileExistsAtPath:[directory stringByAppendingPathComponent:file] isDirectory:&isDir];
    if (!isDir) {
        [contents addObject:[directory stringByAppendingPathComponent:file]];
    }
    else{
        [contents addObject:[directory stringByAppendingPathComponent:file]];
        [contents addObject:[self getFilePathsFromDirectory:[directory stringByAppendingPathComponent:file]]];
    }
}
return contents;
}

- (NSString *)getPathForItemNamed:(NSString *)name array:(NSMutableArray *)arr{
NSString *str;
if (name) {
    for (NSString *s in arr) {
        if ([s isKindOfClass:[NSString class]]) {
            if ([[s lastPathComponent] isEqualToString:name]) {
                return s;
            }
        }
    }
    for (NSMutableArray *aq in arr) {
        if ([aq isKindOfClass:[NSMutableArray class]]) {
            str = [self getPathForItemNamed:name array:aq];
            return str;
        }
    }
}
return str;
}

しかし、問題は、一定量のサブディレクトリ (3 ~ 5) を通過した後、パスが返されなくなり、(null). これは、配列が何らかの理由で戻る前にすべてのディレクトリで埋められていないことに関係しているように感じます。私はこれらをどのように呼んでいますか

NSMutableArray *paths = [self getContentsOfPaths:[self downloadsDir]];

path = [self getPathForItemNamed:[tableView cellForRowAtIndexPath:indexPath].textLabel.text array:paths];
NSLog(@"%@", path);
4

1 に答える 1

1

あなたのgetPathForItemNamed:方法には2つの問題があります:

  • 名前でファイルが見つからない場合、初期化されていない変数の値を返しますstr。これは未定義の動作です。初期化時に に設定する必要がありstrますnil。実際、まったく必要ありませんstr(以下の修正を参照してください)。
  • 最初のサブディレクトリを検出すると、探しているファイルがそのサブディレクトリ内にない場合でも、そのサブディレクトリ内にある必要があると想定します。リターンの最初のレベルの再帰呼び出しが何であれ、getPathForItemNamed:トップレベルの呼び出しの戻り結果になります。これは悪いことです。探しているファイルが 2 番目のサブディレクトリのサブツリーにある場合、それを見つけることはできません!

メソッドを修正する方法は次のとおりです。

- (NSString *)getPathForItemNamed:(NSString *)name array:(NSMutableArray *)arr{
    if (!name) return nil;
    for (NSString *s in arr) {
        if ([s isKindOfClass:[NSString class]]) {
            if ([[s lastPathComponent] isEqualToString:name]) {
                return s;
            }
        }
    }
    for (NSMutableArray *aq in arr) {
        if ([aq isKindOfClass:[NSMutableArray class]]) {
            str = [self getPathForItemNamed:name array:aq];
            // Return something only when you find something
            if (str) return str;
        }
    }
    return nil; // You do not need str at all.
}
于 2013-04-11T02:37:58.547 に答える