1
votes

Fairly new with Objective-c but managed to create a card app from scratch so far. The idea of the game is to play a card game against the pc.

In the function updatePlayerCardView I get the group of cards that a player has and place buttons on the screen with the group names. This works fine for once, but when the function gets called a second time it fails with:

-[CFString retain]: message sent to deallocated instance 0x604ac60

After some debugging and research I figured that the line in which this happens is:

[cardButton setTitle:[NSString stringWithFormat:@"%@ (%i)", [group groupName], [player getCardGroupCount:group]] forState:UIControlStateNormal];

So the NSString gets deallocated obvious, thing what I don't understand is; All the buttons should be recreated, so why do I have a deallocated instance? Is there a better way to update the player view everytime. The amount of buttons is not known from the start.

-(void)updatePlayerCardView { 

 NSMutableArray *groups = [[[game players] objectAtIndex:0] getCardGroups];
 Player *player = [game getPlayer:0];
 int x = 13;
 int y = 157;

 for(int i = 0; i < [groups count]; i++) {
     QuartetGroup *group = [groups objectAtIndex:i];
     int cardGroupCount = [player getCardGroupCount:group];

     if(cardGroupCount == [[game quartet] getCardsPerGroupCount]) {

     }else{
         UIButton *cardButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
         cardButton.frame = CGRectMake(x, y, 140, 37);
         cardButton.tag = i;
         [cardButton setTitle:[NSString stringWithFormat:@"%@ (%i)", [group groupName],[player getCardGroupCount:group]] 
                     forState:UIControlStateNormal];
         [cardButton addTarget:self action:@selector(playerCardClicked:)    forControlEvents:UIControlEventTouchUpInside];
         [[self view] addSubview:cardButton]; 
         //NSLog(@"Card group added to view %@", [group groupName]);
         if( i == 2 || i == 5 || i == 8 || i == 11) {
              x += 157;
              y = 157;
         }else{
              y += 45;
         }
       }
    }
}
2

2 Answers

2
votes

Looks like groupName is deallocated already. It can happens in two cases:

  • You forgot to retain it somewhere. Are you sure it is retained by group?
  • You released somewhere where you should not.

I can propose you two ways how to handle the issue:

  • Read you code carefully to ensure that you manage groupName lifetime properly.
  • You can create MyString class, inherit it from NSString and declare groupName as MyString. Then you can place breakpoint into dealloc method and find when it is deallocated. It may help you to figure out what is wrong with groupName lifetime.
1
votes

First, don't name methods get*. get has a very specific meaning in Cocoa/iOS and a generic getter is not it.

Next, have you used "build and analyze" on your code? Fix all the issues it identifies.

Finally, post the backtrace of where the crash is occurring. Also, post all of the code related to setting and managing the object that is over-released.