1
votes

I have a method set up to remove a sprite on touch, I have several sprites which need to be removed but I have only show one below:

-(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event { 

    ....

    if(CGRectContainsPoint(goalItem.boundingBox, touch)) {
          [self removeChild:goalItem cleanup:YES];
    }

    ....

}

Where goalItem is a CCSprite declared in the header. Basically this causes a crash once the ccTouchEnded method is called again.

I presume this is because the method is looking for goalItem when it has already been removed but I'm not sure.

What is the best way of safely removing a sprite and making sure the pointer doesn't get confused?

I'm very new to cocos2d and objective-c so I'm sure its probably quite a fundamental mistake :/

UPDATE:

I fixed it by creating this method:

-(BOOL)checkForGoalSprite:(CGPoint)point {
if([self.children containsObject:goalItem]){
    if(CGRectContainsPoint(goalItem.boundingBox, point)){
        return YES; 
    }else {
        return NO;
    }
}else{
    return NO;  
}      

}

So it ccTouchEnded reads:

-(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event { 

....

if([self checkForGoalSprite:touch]) {
      [self removeChild:goalItem cleanup:YES];
}

....

}

I'm sure theres a better way...

UPDATE:

I was making the basic error of using if else statements where I could have used if statements, forcing ccTouchEnded to pick only one option.

2
Any crash log?... Please share the output from console when this crash happens. - Tayyab
I get an EXC_BAD_ACCESS. - Alex

2 Answers

1
votes

You are "cleaning up" the sprite, so the pointer is likely to be garbage after this point. I do it by checking the CCSprite object for != nil, then setting it to nil after the removal:

-(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event { 

    ....

    if(goalItem != nil)
    {
        if(CGRectContainsPoint(goalItem.boundingBox, touch)) {
              [self removeChild:goalItem cleanup:YES];
              goalItem = nil;
        }
    }

    ....

}
0
votes

You're probably trying to remove the goalItem from your view's children when it was already removed. Or so it looks like that because the removal is inside the code for handling the touch. Perhaps goalItem could handle the input when it is alive, instead of handling the input for the control on the super-view.