问题
In my code I have CGMutablePathRef thePath = CGPathCreateMutable(); If I don't release it I literally get thousands of leaks because I'm doing the action constantly. However, if I do release it, my game eventually crashes. Any ideas? Is it possible I'm releasing it in the wrong place?
-(void)MoveObject:(int)Tag
{
representationX = gameViewObj.spaceshipImageView.center.x;
representationY = gameViewObj.spaceshipImageView.center.y;
CALayer *spaceshipLayer = gameViewObj.spaceshipImageView.layer;
shipAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
CGMutablePathRef thePath = CGPathCreateMutable();
CGPathMoveToPoint(thePath, NULL, representationX, representationY);
statusFire = YES;
BOOL parsedF = NO;
The remainder of the code is as follows:
-(void)MoveObject:(int)Tag
{
representationX = gameViewObj.spaceshipImageView.center.x;
representationY = gameViewObj.spaceshipImageView.center.y;
CALayer *spaceshipLayer = gameViewObj.spaceshipImageView.layer;
shipAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
CGMutablePathRef thePath = CGPathCreateMutable();
CGPathMoveToPoint(thePath, NULL, representationX, representationY);
statusFire = YES;
BOOL parsedF = NO;
if(Tag==LeftButtonTag)
{
gameViewObj.spaceshipImageView.transform = CGAffineTransformMakeRotation(M_PI + M_PI_2);
previousButtonTag = LeftButtonTag;
representationX--;
CGPathAddLineToPoint(thePath, NULL,representationX, representationY);
parsedF = YES;
}
else if(Tag==UpButtonTag)
{
gameViewObj.spaceshipImageView.transform = CGAffineTransformMakeRotation(0);
previousButtonTag = UpButtonTag;
representationY--;
CGPathAddLineToPoint(thePath, NULL,representationX, representationY);
parsedF = YES;
}
else if(Tag==RightButtonTag)
{
gameViewObj.spaceshipImageView.transform = CGAffineTransformMakeRotation(M_PI/2);
previousButtonTag = RightButtonTag;
representationX++;
CGPathAddLineToPoint(thePath, NULL,representationX, representationY);
parsedF = YES;
}
else if(Tag==DownButtonTag)
{
gameViewObj.spaceshipImageView.transform = CGAffineTransformMakeRotation(M_PI);
previousButtonTag = DownButtonTag;
representationY++;
CGPathAddLineToPoint(thePath, NULL,representationX, representationY);
parsedF = YES;
}
if(parsedF){
shipAnimation.path = thePath;
shipAnimation.delegate = self;
shipAnimation.duration = 0.003;
[spaceshipLayer addAnimation:shipAnimation forKey:@"position"];
//To kill spaceship when moved backwards.
if(playField[representationX][representationY]==3){
[self doDie];
}
if(playField[representationX][representationY] == 2){
if(onSecretLine){
[gameViewObj.spaceshipImageView setCenter:CGPointMake(representationX, representationY)];
oldPositionX = representationX;
oldPositionY = representationY;
}
}
// case: breaking out
if (playField[representationX][representationY]==0){
if (onSecretLine){
if (statusFire)
{
availableOffline = YES;
oldPositionX=gameViewObj.spaceshipImageView.center.x;
oldPositionY=gameViewObj.spaceshipImageView.center.y;
[gameViewObj DrawLine];
onSecretLine = NO;
availableOffline = NO;
}
}
}
if (playField[representationX][representationY]==0)
if (!onSecretLine)
{
BOOL doIt=true;
// ------------------------------
// prevent contact own line
// ------------------------------
// left
if (Tag==LeftButtonTag) {
if (playField[representationX-1][representationY]==3) {
[self doDie];
doIt=false;
}
}
// right
if (Tag==RightButtonTag) {
if (playField[representationX+1][representationY]==3) {
[self doDie];
doIt=false;
}
}
// up
if (Tag==UpButtonTag) {
if (playField[representationX][representationY-1]==3) {
[self doDie];
doIt=false;
}
}
// down
if (Tag==DownButtonTag) {
if (playField[representationX][representationY+1]==3) {
[self doDie];
doIt=false;
}
}
// special things ...
if (doIt)
{
playField[representationX][representationY]=3;
[gameViewObj DrawLine];
}
}
// case: back to the secure line
if (playField[representationX][representationY]==2)
if (!onSecretLine)
{
[gameViewObj.spaceshipImageView setCenter:CGPointMake(representationX, representationY)];
availableOffline = NO;
onSecretLine = YES;
[[NSNotificationCenter defaultCenter] postNotificationName:@"FindBirdCenter" object:nil];
for (int i=0; i<[gameViewObj.birdImageViewArray count]; i++) {
UIImageView* ImgBird=[gameViewObj.birdImageViewArray objectAtIndex:i];
int px=ImgBird.center.x;
int py=ImgBird.center.y;
// cristall point
playField[px][py]=5;
}
[self fillPlaygroundExtended];
//Elan function for filling area enclosed
[self fillAreaEnclosed:gameViewObj._myContext];
// invert ..
[self invertPlayground];
// turn the 3 into -> 20+
[self generateNewSecureLine];
}
if(Tag == UpButtonTag){
[self moveShipUp];
}
else if(Tag == RightButtonTag){
[self moveShipRight];
}
else if(Tag == DownButtonTag){
[self moveShipDown];
}
else if(Tag == LeftButtonTag){
[self moveShipLeft];
}
if(doScore == YES){
[self calculateScore];
doScore = NO;
}
[gameViewObj setNeedsDisplay];
}
}
回答1:
You never release thePath. At least not in that code snippet.
Core Graphics uses the Core Foundation Memory Rules, which you can read at Memory Management Programming Guide for Core Foundation
In short: Any function that contains Create in its name will return a retained object that you will need to release with a function that Release in it's name. In case of a CGPathRef there is CGPathRelease.
回答2:
You should perform a CGPathRelease() on your path after the line
shipAnimation.path = thePath;
as well as in an else statement for the
if(parsedF){
condition (otherwise it will still leak if parsedF is NO.
来源:https://stackoverflow.com/questions/2209559/where-am-i-leaking-cgmutablepathref-in-this-code