Pregunta

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!

¿Fue útil?

Solución

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.

Otros consejos

imageNamed: uses the internal cache which does not empty itself on memory warnings. Try imageWithData

- (void)didReceiveMemoryWarning {

    if([self isViewLoaded] && self.view.window == nil) {
       self.view = nil;
    }

    [super didReceiveMemoryWarning];
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top