Chris Loonam
Chris Loonam

Reputation: 5745

iOS array not being filled completely

I am using these two recursive methods to find the paths of files and directories in a certain folder

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

but the problem is, after going through a certain amount of subdirectories (3-5), this stops returning any path and returns (null). I feel like this has to do with the array not being filled with all the directories before it returns for some reason. Heres how I call these

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

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

Upvotes: 2

Views: 111

Answers (1)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727067

There are two problems with your getPathForItemNamed: method:

  • When it cannot find a file by name, it returns a value of an uninitialized variable str. This is undefined behavior - you need to set str to nil upon initialization. In fact, you do not need str at all (see the fix below).
  • When it discovers its first subdirectory, it assumes that the file that it is looking for must be inside that subdirectory, even if it is not. Whatever the first-level recursive invocation of getPathForItemNamed: returns, becomes the return result of the top-level invocation. This is bad: if the file that you are looking for is in the subtree of the second subdirectory, you are never going to find it!

Here is how you can fix your method:

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

Upvotes: 1

Related Questions