Search code examples
iosobjective-cnsrangeexception

Receive NSRangeException error message "objectAtIndex beyond bounds"


In one class called LevelSelectViewController, I have this public property

    @property (nonatomic, strong, getter=getLevelNumber) NSNumber *levelNumber;

which stores an int value based on a UIButton* touch selection using the method

     - (IBAction)buttonPressedSoWhatNumber:(id)sender
     {
         UIButton *button = (UIButton *)sender;
         int row = button.tag;
         _levelNumber = [NSNumber numberWithInt:row];
     }

When I put a breakpoint at the end of the method to see if my touch interaction triggers the correct result based on what I coded (when I press button 1, really), _levelNumber reads 0 (which it should). I also have a getter method written out for it.

Now, in this second class called GameViewController, I have a method setUpBoards which (should) obtain that value for *levelNumber. It looks like this:

    - (void)setUpBoards {
        LevelSelectViewController* level = [[LevelSelectViewController alloc] init];
        [level getLevelNumber];
        [self createLevelModel:(int)level];
    }

In that same class, the method createLevelModel:(int)levelIndex uses that value to be passed to 5 initialization methods that access a Levels.plist file to load data for my game.

Basically, that number represents what level button I pressed and uses that number to load the correct level. In another manner, I have verified that those 5 initialization methods work along with loading data from my Levels.plist file.

Now, between the transition from LevelSelectViewController to GameViewController, I receive the NSRangeException error message:

   'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (554166800) beyond bounds (1)'

even when pressing the 1 button (which should work considering I only have Item 0 in my plist typed out.......which, again, I verified worked using another manner).

TO ADD ON TO THIS. Here's another important method:

    -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
             cellForItemAtIndexPath:(NSIndexPath *)indexPath {

        static NSString *cellIdentifier = @"cvCell";
        CVCell *cell = (CVCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
        NSMutableArray *data = [self.dataArray objectAtIndex:indexPath.section];
        NSString *cellData = [data objectAtIndex:indexPath.row];
        [cell.buttonClick setTag:indexPath.row];
        [cell.buttonClick addTarget:self action:@selector(buttonPressedSoWhatNumber:)
           forControlEvents:UIControlEventTouchUpInside];
        [cell addSubview:cell.buttonClick];
        return cell;
    }

Any insight?

Here's the push controller method from LevelSelectViewController to GameViewController:

    -(IBAction)buttonPressed:(id)sender {
         GameViewController* obj = [[GameViewController alloc] initWithNibName:@"GameViewController" bundle:nil];
         [self.navigationController pushViewController:obj animated:YES];
    }

buttonPressed: is another method given to the UIButton*


Solution

  • You need a simple int property in LevelSelectViewController that you can use to store the level that has been selected:

    @property int levelSelected;
    

    The store the selected value in your button press handler:

    - (IBAction)buttonPressedSoWhatNumber:(UIButton *)sender
    {
         self.levelSelected = sender.tag;
    }
    

    Then you can pass this to a corresponding int property on your GameViewController;

    -(IBAction)buttonPressed:(id)sender {
         GameViewController* obj = [[GameViewController alloc] initWithNibName:@"GameViewController" bundle:nil];
         obj.level = self.selectedLevel
         [self.navigationController pushViewController:obj animated:YES];
    }