iOS数组未完全填充

时间:2013-04-10 23:34:03

标签: iphone ios objective-c nsmutablearray

我正在使用这两种递归方法来查找某个文件夹中文件和目录的路径

- (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);

1 个答案:

答案 0 :(得分:1)

getPathForItemNamed:方法存在两个问题:

  • 当它无法按名称查找文件时,它会返回未初始化变量str的值。这是未定义的行为 - 您需要在初始化时将str设置为nil。实际上,您根本不需要str(请参阅下面的修复程序)。
  • 当它发现它的第一个子目录时,它假定它正在寻找的文件必须在该子目录中,即使它不是。无论getPathForItemNamed:的第一级递归调用返回什么,都将成为顶级调用的返回结果。这很糟糕:如果您要查找的文件位于第二个子目录的子树中,那么您永远不会找到它!

以下是修复方法的方法:

- (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.
}