I always used ARC but my cocos2d template doesn’t use ARC, to I have to use the manual ref counting and that’s probably why I crash.
The goal is to make a menu with two labels, if I click to a label, I show an image with a sprite.If I click on the image, I can go back to the menu and choose again.
This is the CCLayer class:
-(id) init
{
if( (self=[super init]))
{
CCMenuItemLabel* item1, *item2;
CCLabelTTF* label1= [CCLabelTTF labelWithString: @"Shark Icon" fontName: @"Arial" fontSize: 30], *label2;
label2= [CCLabelTTF labelWithString: @"Cocos2D Icon" fontName: @"Arial" fontSize: 30];
label1.color= ccRED;
label2.color= ccRED;
[label1 retain];
[label2 retain];
item1=[CCMenuItemLabel itemWithLabel: label1 block:^(id sender)
{
NSLog(@"Clicked shark icon");
[self removeChild: menu cleanup: NO];
shark=[CCSprite spriteWithFile: @"shark.jpeg"];
[shark setPosition: CGPointMake(150, 200)];
[self addChild: shark];
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate: self priority: 0 swallowsTouches: YES];
}];
item2= [CCMenuItemLabel itemWithLabel: label2 block:^(id sender)
{
NSLog(@"Clicked cocos2d icon");
[self removeChild: menu cleanup: NO];
icon=[CCSprite spriteWithFile: @"icon.png"];
[icon setPosition: CGPointMake(150, 200)];
[self addChild: icon];
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate: self priority: 0 swallowsTouches: YES];
}];
[item1 retain];
[item2 retain];
menu=[CCMenu menuWithItems: item1,item2, nil];
[menu alignItemsVertically];
[self addChild: menu];
}
return self;
}
- (BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
[[CCTouchDispatcher sharedDispatcher] removeDelegate: self];
[self removeChild: shark cleanup: NO];
[self addChild: menu];
return YES;
}
What happens: I click on “Shark Icon” (or “Cocos2D Icon”), then the shark image appears,if I click on it I get EXC_BAD_ACCESS:
EXC_BAD_ACCESS (code=1, address= 0x70Baafc8)
I tried to print all addresses (menu, item1,etc…), and no one of the items has this address.Sometimes I even get an invalid address like 0x00000008 .
EDIT
I would solve the problem by just retaining menu, but I haven’t understood why: menu is already retained:
@property (nonatomic, retain) CCSprite* shark;
@property (nonatomic, retain) CCSprite* icon;
@property (nonatomic, retain) CCMenu* menu;
If I enable zombies I get this:
*** -[CCMenu tag]: message sent to deallocated instance 0x7c71a10
So menu is a zombie but shouldn’t the retain property make it be retained?
The strange thing is that I don’t need to retain shark and icon, just menu.
menu was never retained. if its a retain property use self.menu
you create a new shark every time but want to reuse your menu!