我在这个代码中泄漏CGMutablePathRef在哪里?

时间:2010-02-05 18:53:23

标签: iphone cocoa-touch core-animation core-graphics

在我的代码中我有CGMutablePathRef thePath = CGPathCreateMutable();如果我不释放它,我实际上会得到成千上万的泄漏,因为我不断地采取行动。但是,如果我发布它,我的游戏最终会崩溃。有任何想法吗?我有可能在错误的地方发布它吗?

-(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;

代码的其余部分如下:

-(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];
    }
}

2 个答案:

答案 0 :(得分:9)

您应该在行

之后的路径上执行CGPathRelease()
shipAnimation.path = thePath;

以及

的else语句
if(parsedF){

条件(否则如果parsedF为NO,它仍然会泄漏。

答案 1 :(得分:5)

您永远不会发布thePath。至少不在那段代码中。

Core Graphics使用核心基础内存规则,您可以在Memory Management Programming Guide for Core Foundation

阅读

简而言之:任何名称中包含Create的函数都将返回一个保留的对象,您需要使用其中Release的名称来释放该对象。如果CGPathRefCGPathRelease