In my split view iPad app the default detail view loads a random image from an array and does this any time the user goes back to that view. The app loads fine with that view and I can go to another view fine. The problem is that if I go back to that view, sometimes it will crash and sometimes it will crash if I select another view after going back to the default view. I do not show any leaks when I run the leaks tool and I don't show anything in the log every time a crash occurs. I did receive a "Received Memory Warning" log once so it the crashes must have something to do with a leak somewhere, I'm just not sure where. I am using ARC. Any ideas?
Here is my viewDidLoad method:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIImage *agelity = [UIImage imageNamed:@"Agelity"];
UIImage *agelity2 = [UIImage imageNamed:@"Agelity2"];
UIImage *biltmore = [UIImage imageNamed:@"Biltmore"];
UIImage *biltmore2 = [UIImage imageNamed:@"Biltmore2"];
UIImage *biltmore3 = [UIImage imageNamed:@"Biltmore3"];
UIImage *choice = [UIImage imageNamed:@"Choice"];
UIImage *enterprise = [UIImage imageNamed:@"Enterprise"];
UIImage *enterprise2 = [UIImage imageNamed:@"Enterprise2"];
UIImage *grainger = [UIImage imageNamed:@"Grainger"];
UIImage *grainger2 = [UIImage imageNamed:@"Grainger2"];
UIImage *greatWolf = [UIImage imageNamed:@"Great_Wolf"];
UIImage *greatWolf2 = [UIImage imageNamed:@"Great_Wolf2"];
UIImage *officeDepot = [UIImage imageNamed:@"Office_Depot1"];
UIImage *officeDepot2 = [UIImage imageNamed:@"Office_Depot2"];
UIImage *officeDepot3 = [UIImage imageNamed:@"Office_Depot3"];
UIImage *sams = [UIImage imageNamed:@"Sams"];
UIImage *sams2 = [UIImage imageNamed:@"Sams2"];
NSMutableArray *benefitAds = [[NSMutableArray alloc]initWithObjects:agelity, agelity2, biltmore, biltmore2, biltmore3, choice, enterprise, enterprise2, grainger, grainger2, greatWolf, greatWolf2, officeDepot, officeDepot2, officeDepot3, sams, sams2, nil];
int randomIndex = arc4random() % [benefitAds count];
adImage.image = [benefitAds objectAtIndex:randomIndex];
[self configureView];
}
EDIT: I am trying to use the suggestion of using imageWithData instead of imageNamed so I'm doing this:
NSData *agelityData = [NSData dataWithContentsOfFile:@"Agelity"];
UIImage *agelity = [UIImage imageWithData:agelityData];
but now the app crashes at launch with on the line:
int randomIndex = arc4random() % [benefitAds count];
with:
Thread 1: EXC_ARITHMETIC(code=EXC_I386_DIV, subcode=0x0)
When I run it on my device instead of the simulator, I get this:
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 3051310543 beyond bounds for empty array'
EDIT: I set an exception breakpoint because I'm getting an exc_bad_access code=1 error. It looks like the app randomly crashes at times when I'm changing the detail view. I guess I'll create a new question.
Thanks for all the help!
I don't know if it is exactly this that is causing the crash (high chances that it might be), but I really suggest you to don't store all images inside your array.
A better approach would be store the name of the images, and the allocate just one UIImage, with the name selected.
See this:
- (void)viewDidLoad
{
NSMutableArray *benefitAds = [[NSMutableArray alloc]initWithObjects:@"Agelity", @"Agelity2", @"Biltmore", @"Biltmore2", @"Biltmore3", @"Choice", @"Enterprise", @"Enterprise2", @"Grainger", @"Grainger2", @"Great_Wolf", @"Great_Wolf2", @"Office_Depot1", @"Office_Depot2", @"Office_Depot3", @"Sams", @"Sams2", nil];
int randomIndex = arc4random() % [benefitAds count];
if(randomIndex < [benefitAds count]) {
adImage.image = [UIImage imageNamed:[benefitAds objectAtIndex:randomIndex]];
[self configureView];
}
else
{
//error message
}
}
Please give some feedback it worked or not.
EDIT:
Try to check if the random number get is really a valid index before using it.