Jordan Williams
Jordan Williams

Reputation: 3

Objective-C - Returning an NSArray from custom instance method returns nil

I have been racking my brain around why I'm getting the results I am, however people will note I'm a beginner objc dev.

Ignoring the fact there were different ways to go about what I'm trying to do (extending NSFileManager for example), I'd love some input if not too much of an amateur mistake.

If I break during the return of the instance method listFilesForURL, the returned NSArray object 'theFiles' is good to go. I get the results I expect, however in main.c, 'listOfFiles' is always nil.

Can someone point out what I'm failing to see? Any input is greatly appreciated!

main.c

#import <Foundation/Foundation.h>
#import "FileManipulator.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        // insert code here...

        FileManipulator *myFileManipulator = [[FileManipulator alloc] init];
        NSArray *listOfFiles = [myFileManipulator listFilesForURL:[NSURL fileURLWithPath:@"/tmp"]];

    }
    return 0;
}

FileManipulator.h

#import <Foundation/Foundation.h>

@interface FileManipulator : NSObject

- (id)initAndCopySourceURL:(NSURL *)srcURL toDestination:(NSURL *)destURL;
- (NSArray*)listFilesForURL:(NSURL *)srcURL;

@end

FileManipulator.m

#import "FileManipulator.h"

@implementation FileManipulator

- (id)initAndCopySourceURL:(NSURL *)srcURL toDestination:(NSURL *)destURL {

    self = [super init];
    if (self != nil) {
        NSError *copyError;
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if ([fileManager fileExistsAtPath:[srcURL relativePath]]) {
            NSLog(@"File exists: %@", [srcURL relativePath], nil);
            if ([fileManager copyItemAtURL:srcURL toURL:destURL error:&copyError]) {
                NSLog(@"File copied successfully to %@", [destURL relativePath]);
            } else {
                NSLog(@"File not copied, error was: %@", [copyError localizedFailureReason] );
            }
        }

    }
    NSLog(@"Init. FileManipulator Class");

    return self;
}

- (NSArray *)listFilesForURL:(NSURL *)srcURL {

    NSError *listFilesError;
    NSLog(@"listFilesForURL Entered");
    NSFileManager *myFileManager = [NSFileManager defaultManager];
    NSArray *theFiles = [myFileManager contentsOfDirectoryAtPath:[srcURL path] error:&listFilesError];
    return theFiles;
}

@end

Upvotes: 0

Views: 1717

Answers (2)

CodaFi
CodaFi

Reputation: 43330

I see two reasons why this could fail:

  1. Your file URL is either inaccessible, doesn't exist, or isn't in a format NSFileManager likes. The path to the temporary directory for an application should be accessed with NSTemporaryDirectory().

  2. ARC or no ARC, anything you're not using, you're losing - memory management-wise that is. Ignoring the fact that your main includes un-referenced variables that are ripe for being stripped out as dead code, when the end of that @autoreleasepool block is reached, anything inside of it should be dead (as it is so close to a return statement. Autorelease pools involved in applications with any kind of run loop make no guarantees about object lifecycles). Which means you should be logging immediately after invoking the method so you can least get a reliable foothold before it gets deallocated.

Upvotes: 1

Camo
Camo

Reputation: 1778

try by doing this:

NSString  *tmp = [NSHomeDirectory() stringByAppendingPathComponent:@"tmp"];
NSArray *listOfFiles = [myFileManipulator listFilesForURL:[NSURL fileURLWithPath:tmp]];

Upvotes: 0

Related Questions