Paul Sommers
Paul Sommers

Reputation: 63

Objective C - NSArray and For loop structure

Work got in the way of learning Objective C but i'm back at it now and this has been driving me crazy.

This is my code:

i=0;
    for (i=0;[photoList count]; i++) {
        NSLog(@"%i",i);
        NSLog(@"%@",[photoList objectAtIndex:i]);
        NSString *fileName = [photoList objectAtIndex:i];
        sendImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fileName ofType:nil]];
        UIImageWriteToSavedPhotosAlbum(sendImage,self,@selector(savedPhotoImage:didFinishSavingWithError:contextInfo:),NULL);}

photoList is just an NSArray like so, except with 24 objects:

NSArray* photoList = [NSArray arrayWithObjects:@"Photo 1.jpg",
    @"Photo 2.jpg",
    @"Photo 3.jpg",
    @"Photo 4.jpg",nil];

It works... It copies the photos to the camera roll... and then crashes with

2010-07-24 19:34:36.116 iCardz2go Poindexter[29662:207] * Terminating app due to uncaught exception 'NSRangeException', reason: '* -[NSArray objectAtIndex:]: index 24 beyond bounds [0 .. 23]'

I've tried various configurations such as

for (i=0;1<23; i++)

only to get 2010-07-24 19:51:01.017 iCardz2go Poindexter[29908:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSInvocation invocationWithMethodSignature:]: method signature argument cannot be nil'

So it's reading the nil and passing it.

I know its going to be something real simple that I've forgotten. Why doesn't it jump out the loop at Photo 23 (the count)?

Your help is greatly appreciated! P

Upvotes: 5

Views: 32039

Answers (5)

Ohmy
Ohmy

Reputation: 2221

Change your for statement to for(i=0; i<[photoList count]; i++)

Upvotes: 0

Geri Borb&#225;s
Geri Borb&#225;s

Reputation: 16598

From your code:

for (i=0;[photoList count]; i++)

The condition [photoList count] is always true. I didn't read the whole discussion, though.

Upvotes: 0

Jonathan Grynspan
Jonathan Grynspan

Reputation: 43472

For loops in C and Objective-C look like this:

for (initialization; condition; increment) {
    // body
}

initialization is where you set up the loop; it's where you tell it what to start with. condition is tested for each iteration, including the first; if the condition evaluates to true, the body of the loop is executed. At the end of each iteration, increment is evaluated.

So:

for (int i = 0; i < 10; i++) {
    printf("%i\n", i);
}

Will print the numbers 0 through 9. What you probably want for yours is:

NSUInteger count = [photoList count];
for (NSUInteger i = 0; i < count; i++) {
    NSString *fileName = [photoList objectAtIndex: i];
    sendImage = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: fileName ofType: nil]];
    UIImageWriteToSavedPhotosAlbum(sendImage, self, @selector(savedPhotoImage:didFinishSavingWithError:contextInfo:), NULL);
}

Note the assignment of count outside the loop; it's simply an optimization so the loop doesn't have to send an extra message for each iteration (you could just as easily do i < [photoList count].)

Does that help?

Upvotes: 13

Marcelo Cantos
Marcelo Cantos

Reputation: 185852

Both for-loop conditions — [photoList count] and 1<23 — always evaluate to true. Try i < [photoList count]. Better still, use @Eimantas's answer.

Upvotes: 4

Eimantas
Eimantas

Reputation: 49354

Why don't you try fast enumeration?

for (NSString *photoFile in photoList) {
  NSLog(@"%@", photoFile);
  sendImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] 
                               pathForResource:photoFile 
                                        ofType:nil]];

  UIImageWriteToSavedPhotosAlbum(sendImage, self, @selector(savedPhotoImage:didFinishSavingWithError:contextInfo:), NULL);}
}

Upvotes: 21

Related Questions