John
John

Reputation: 3115

Handling UIButtons iOS

I've been watching the iOS lectures(by Paul Hegerty) from Winter 2013 and I can't seem to wrap my head around why this second line of code is necessary in the Matchisimo program. If I comment it out, the program crashes, but if I leave it in, it works fine.

[cardButton setTitle:card.contents forState:UIControlStateSelected];

[cardButton setTitle:card.contents forState:UIControlStateSelected|UIControlStateDisabled];

Fails at this line:

@autoreleasepool {
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([CardGameAppDelegate class]));
}

Error given if the second line is commented out:

'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 47 beyond bounds [0 .. 46]'

Card contents:

@property (strong, nonatomic) NSString *contents;

Update UI:

- (void)updateUI
{
    for (UIButton *cardButton in self.cardButtons) {
        Card *card = [self.game cardAtIndex:[self.cardButtons indexOfObject:cardButton]];

        [cardButton setTitle:card.contents forState:UIControlStateSelected];

        [cardButton setTitle:card.contents forState:UIControlStateSelected|UIControlStateDisabled];

        cardButton.selected = card.isFaceUp;
        cardButton.enabled = !card.isUnPlayable;
    }
}

Upvotes: 0

Views: 146

Answers (1)

Ryan Poolos
Ryan Poolos

Reputation: 18551

Commenting this line [cardButton setTitle:card.contents forState:UIControlStateSelected|UIControlStateDisabled]; does not cause a crash for any reason.

This is the line [self.game cardAtIndex:[self.cardButtons indexOfObject:cardButton]]; causing a crash related to an index out of bounds. Basically you have more cardButtons than self.game has cards.

You can wrap it with this to prevent a crash but should look for the deeper underlying problem for why an extra button is created.

int buttonIndex = [self.cardButtons indexOfObject:cardButton];
if (self.game.count > buttonIndex) {
    Card *card = [self.game cardAtIndex:buttonIndex];

    [cardButton setTitle:card.contents forState:UIControlStateSelected];

    [cardButton setTitle:card.contents forState:UIControlStateSelected|UIControlStateDisabled];

    cardButton.selected = card.isFaceUp;
    cardButton.enabled = !card.isUnPlayable;
}

Upvotes: 3

Related Questions