开发者

Where am I leaking CGMutablePathRef in this code?

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)MoveObj开发者_如何学JAVAect:(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];
    }
}


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜