Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

mike1360

macrumors newbie
Original poster
Nov 9, 2013
13
0
Getting the error above causing my iOS app to crash. Never seen this before and was wondering if anyone could help me? I'm new to coding and taking on my first app without following lessons/tutorials.
Code:
-(void)updateGamePlay {
    int numberOfImages = (int)[self.mainImages count];
    int randomIndex = arc4random() % numberOfImages;
    MainImage *imageView = [self.mainImages objectAtIndex:randomIndex];
 
    self.mainImageView.image = imageView.mainTextImage;
}

It appears on the second line with the
Code:
int randomIndex = arc4random() % numberOfImages;

What i have is an array called mainImages.
That array holds objects which have a property of UIImage called mainTextImage. Inside this method, I am trying to set mainTextImage equal to mainImageView.image so that when this method is called, one of those images are randomly selected to be displayed in the mainImageView.

My array looks like this (inside another class file)
Code:
- (NSArray *)mainImages {
    NSArray *mainImages = [[NSArray alloc] initWithObjects:
                            [UIImage imageNamed:@"purpleText.png"]
                           ,[UIImage imageNamed:@"whiteText.png"]
                           ,[UIImage imageNamed:@"blackText.png"]
                           ,nil];
    return mainImages;
}

Thanks!
 
This might be a 'divide by zero' error. Or an error when the random number is below the numberOfImages.

Anyway, you should be able to debug this by assigning the random number to a local variable and printing out both the random number and numberOfImages before calculating randomIndex and then seeing what values cause the crash.
 
If I google for the word EXC_1386_DIV from your error message, it shows this StackOverflow thread in the top results:
http://stackoverflow.com/questions/13812269/exc-arithmetic-when-accessing-random-elements-of-nsarray

Two points from the answer:
The error you're getting (an arithmetic exception) is because [the array] is empty and this leads to a division by zero when you perform the modulus operation.

You have to explicitly check for the case of an empty ... array. Also you should use arc4random_uniform for avoiding modulo bias.

Googling the text from your error message is a useful tool for finding others who may have had the same problem before you, and learning what their solution was.


And I agree with PhoneyDeveloper's suggestion: assign the two values to variables and print them. I will warn you, however, if the array isn't empty immediately, you could print a whole lot of numbers before the array count goes to 0.

I upvoted PhoneyDeveloper's post because it's a debugging or diagnostic tool that's appropriate in many situations, and is worthwhile to learn and reuse.
 
It was in fact a divide by 0 error. I also looked into the arc4random_Uniform a bit and came out with this.

Code:
-(void)updateGamePlay {
    int randomIndex = arc4random_uniform((int)self.mainImages.count);
    MainImage *imageView = [self.mainImages objectAtIndex:randomIndex];
    
    self.mainImageView.image = imageView.mainTextImage;
}

There are no longer any errors but the code doesn't function properly. No image is displayed at all.
 
It was in fact a divide by 0 error. I also looked into the arc4random_Uniform a bit and came out with this.

Code:
-(void)updateGamePlay {
    int randomIndex = arc4random_uniform((int)self.mainImages.count);
    MainImage *imageView = [self.mainImages objectAtIndex:randomIndex];
    
    self.mainImageView.image = imageView.mainTextImage;
}

There are no longer any errors but the code doesn't function properly. No image is displayed at all.

1. What is the value of randomIndex? If it's always the same (e.g. always 0), then what is the value of count being passed to the function?

2. What is the value of imageView? Specifically, is it nil or not? If it's nil, how might that have happened (i.e. double-check every value stored in self.mainImages)

3. If imageView is non-nil, what is the value of its mainTextImage property? I.e. is the property nil or non-nil?

You can use NSLog or the debugger to get answers to all those questions. If you don't know how to use either one, then you need to learn one of them, and probably practice how it works on a known-working program. For example, go back to one of the programs you wrote as an exercise when you were learning, and either step through it in the debugger, or add NSLog statements that print important values.

The reason for practicing on a known-working program is because you should already understand everything it does, and thus understand everything that NSLog or the debugger shows you.


The above questions are all ones that arise when you Break Things Down, which is a fundamental debugging strategy.

Break the problem down into smaller steps or parts, until you can manually confirm each step or part. Then confirm what each step or part actually is.

Confirming each step or part is another fundamental debugging strategy: Confirm Your Expectations.

There are two elements to Confirm Your Expectations. The first element isn't Confirm, it's Expectations. If you don't know what to expect, then you don't understand the problem well enough to confirm a value or solve the problem. If you do know what to expect, then you know what to look for in the second element: Confirmation. If you see something you expect, go on to the next step or part of Break Things Down. If you see something unexpected, make sure you understand why it's happening before you go on.
 
1. What is the value of randomIndex? If it's always the same (e.g. always 0), then what is the value of count being passed to the function?

2. What is the value of imageView? Specifically, is it nil or not? If it's nil, how might that have happened (i.e. double-check every value stored in self.mainImages)

3. If imageView is non-nil, what is the value of its mainTextImage property? I.e. is the property nil or non-nil?

You can use NSLog or the debugger to get answers to all those questions. If you don't know how to use either one, then you need to learn one of them, and probably practice how it works on a known-working program. For example, go back to one of the programs you wrote as an exercise when you were learning, and either step through it in the debugger, or add NSLog statements that print important values.

The reason for practicing on a known-working program is because you should already understand everything it does, and thus understand everything that NSLog or the debugger shows you.


The above questions are all ones that arise when you Break Things Down, which is a fundamental debugging strategy.

Break the problem down into smaller steps or parts, until you can manually confirm each step or part. Then confirm what each step or part actually is.

Confirming each step or part is another fundamental debugging strategy: Confirm Your Expectations.

There are two elements to Confirm Your Expectations. The first element isn't Confirm, it's Expectations. If you don't know what to expect, then you don't understand the problem well enough to confirm a value or solve the problem. If you do know what to expect, then you know what to look for in the second element: Confirmation. If you see something you expect, go on to the next step or part of Break Things Down. If you see something unexpected, make sure you understand why it's happening before you go on.

I appreciate the advice and will start working harder and closer at any errors that arise. Thank you for all your help
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.