tags:

views:

302

answers:

5

i get the signal error EXC_BAD_ACCESS when trying to retrieve the return output from the randomBallPick method, i probably do it wrong.

NSString *temp = [self randomBallPick];
upBall1.image = [UIImage imageNamed:temp];
A: 

As soon as you remove the object from the array, its retain count is probably zero, and it will get dealloced. Try doing

return [[chosenFilename] retain] autorelease]
Rudedog
no, error, you sure you syntax it right?
omri
return [[chosenFilename retain] autorelease];still EXC_BAD_ACCESS
omri
A: 

Array (containers) retain/release items that are added/removed.

The object will receive release when it's removed from container with removeObjectAtIndex: so you need to retain it before it is removed and possibly autorelease since you are returning it from your method.

NSString * chosenFilename =
          [[[imageArray objectAtIndex:chosen] retain] autorelease];
[imageArray removeObjectAtIndex:chosen];
return chosenFilename;
stefanB
still the same problem
omri
now it should work, I tested it
stefanB
perfect! thanks :-)
omri
To more clearly see how a return value is memory managed it usually a good idea to put the autorelease at the very end.NSString * chosenFilename = [[imageArray objectAtIndex:chosen] retain]];[imageArray removeObjectAtIndex:chosen];return [chosenFilename autorelease];
monowerker
Hm, yeah I don't have preference as long as it works.
stefanB
A: 

OK, can you try this, please?

NSString *chosenFilename = [[imageArray objectAtIndex:chosen] retain];
[imageArray removeObjectAtIndex:chosen];
return [chosenFilename autorelease];
Thomas Müller
A: 

All you need to do is:

NSString *chosenFilename = [[imageArray objectAtIndex:chosen] retain];

Since the objectAtIndex method returns an autorelease object.

yandy
A: 

There are several things wrong with this piece of code.

You are initializing your array of names once, but then you keep removing stuff from it... I'm not sure you want to do this, otherwise you'll start returning nil exclusively (after the 38th call...). You may want to re-fill your array in that case. Here's a better version of your routine (I think):

static NSMutableArray *imageArray = nil;

if (!imageArray.count) {
    if (imageArray==nil) imageArray = [[NSMutableArray alloc] init];
    for (int c = 0; c < 37; c++)
    {
        NSString *imageName = [NSString stringWithFormat:@"ball_%i.png", c];
        [imageArray addObject:imageName];
    }
}
// Now we are basically sure that imageArray.count > 0
assert(imageArray.count>0);
NSUInteger chosen = arc4random() % imageArray.count;
NSString *chosenFilename = [[imageArray objectAtIndex:chosen] retain];
[imageArray removeObjectAtIndex:chosen];
return [chosenFilename autorelease];

As others have said, you have to retain then autorelease the strings you extract from the array (because the array releases them upon removal).

Note also that you should call 'retain' on the string before removing it from the array. The string is already released after the removeObjectAtIndex: call... so it's already too late to retain it then.

Zoran Simic
Count is not a property, so it shouldn't be accessed using the dot notation. He did need to set imageArray to nil at the start above, but it's perfectly valid to check imageArray's pointer like he does above.
Brad Larson