views:

165

answers:

1

Hi, I have some problems to retreive folder names and send them as items for a ComboBox

My actual code:

NSError *errors = nil;
NSString *pathForDirectory = @"/Folder/Folder/";
NSFileManager* fileManager = [NSFileManager defaultManager];
NSArray *contentsDirectory = [fileManager contentsOfDirectoryAtPath:
                             pathForDirectory error:&errors];
NSArray *Directory = [NSArray arrayWithObjects:contentsDirectory];

dataFromArray = [[NSMutableArray alloc] init];
[dataFromArray addObjectsFromArray:Directory];  

[self sortItemInMyComboBox:dataFromArray];

So, if NSArray *Directory is defined with static array, it works, but with the code above, the app crash with log error: Terminating app due to uncaught exception 'NSRangeException', reason: ' -[NSCFArray objectAtIndex:]: index (2147483647( or possibly larger)) beyond bounds (3)'

I guess, my mistake is how i use NSFileManager, but i've tried to others methods whitout success.

Thanks in advance, Ronan.

+5  A: 

Problem

[NSArray arrayWithObjects:contentsDirectory];

Solution (See below for a better solution.)

[NSArray arrayWithArray:contentsDirectory];

Reason

+ (NSArray *)arrayWithObjects: excepts a nil-terminated list like this:

NSArray *fruits = [NSArray arrayWithObjects:@"Apple", @"Grape", @"Banana", nil];

If it can't find nil it tries to add objects which don't exists. This leads to an ugly error message, not necessarily the one you encountered.


BTW:

Your code looks too complicated, it should be something like this:

NSError *error = nil;
NSString *path = @"/Folder/Folder/";
NSFileManager* fileManager = [NSFileManager defaultManager];
NSArray *directory = [fileManager contentsOfDirectoryAtPath:pathForDirectory
                                                      error:&error];

if (error) {
    // do something about it
}

// You don't need autorelease if you use garbage collection
NSMutableArray *files = [[directory mutableCopy] autorelease];
// this looks like it violates the MVC pattern, have you
// thought about using bindings?
[self sortItemInMyComboBox:files];
Georg
+1 Good answer. Most of your code changes are good, but it's always correct to autorelease — GC won't add it to an autorelease pool as would happen under Retain-Release, but it the collector can use it as a hint. Also, to reach the widest audience and be able to use any third-party framework, it's best practice to write "dual-mode" code that works under both RR and GC.
Quinn Taylor
GS: thanks for corrections. As you suggested, i've used binding, so the final result looks this:...NSMutableArray *files = [directory mutableCopy];[dataFromArray addObjectsFromArray:files];Where dataFromArray is the NSComboxBox outlet. Bind with the main controller (model key path: self.dataFromArray).Then works. Thanks Again.Ronan.
ronan