Spritekit 节点未从内存中删除

Posted

技术标签:

【中文标题】Spritekit 节点未从内存中删除【英文标题】:Sprite kit node not being removed form memory 【发布时间】:2014-05-01 17:12:01 【问题描述】:

我的 sprite kit 游戏一直存在内存问题,我已经尝试了我所知道的一切来修复它,但仍然没有。关于这个问题的一点背景;第一次玩游戏,记忆力很好,完全稳定。但是,当你死去并再次点击播放时,那是记忆开始爬升的时候。似乎你玩得越多,记忆就会越快。您可以在任何场景中,并且正在使用的内存仍然会攀升。这是一张显示乐器的图片,http://postimg.org/image/5olu8h7tp/。

这是我的代码:

创建对象:

 -(void)createObstacle0 

int yMin = (CGRectGetMidY(self.frame)+190);
int yMax = (CGRectGetMidY(self.frame)+270);
CGPoint startPoint = CGPointMake(-20, yMin + arc4random_uniform(yMax - yMin));
SKSpriteNode *obstacle = [SKSpriteNode spriteNodeWithImagedNamed:@"obstacle"];
obstacle.position = CGPointMake(startPoint.x, startPoint.y);
obstacle.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:21];
obstacle.physicsBody.categoryBitMask = enemyCategory;
obstacle.physicsBody.contactTestBitMask = playerCategory;
obstacle.physicsBody.dynamic = NO;
obstacle.name = @"obstacle";
[self addChild:obstacle];
SKAction *move = [SKAction moveTo:CGPointMake(340, startPoint.y) duration:minTime +arc4random_uniform(maxTime - minTime)];
SKAction* removeObstacle = [SKAction removeFromParent];
[obstacle runAction:[SKAction sequence:@[move, removeObstacle]] completion:^
    score++;
    scorelabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)score];
];
float randomNum = arc4random_uniform(3.0) + 0.2;
[self performSelector:@selector(createObstacle0) withObject:nil afterDelay:randomNum];

碰撞检测器和场景转换:

-(void)didBeginContact:(SKPhysicsContact *)contact

uint32_t collision = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask);
if (collision == (playerCategory | enemyCategory)) 

playerAlive = NO;

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setInteger:score forKey:@"playerScore"];
    [defaults synchronize];

    int highScore = [[[NSUserDefaults standardUserDefaults] objectForKey:@"High Score"] integerValue];
    if (highScore)
        if (highScore < score)
            [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:score] forKey:@"High Score"];
        
    
    else
        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:score] forKey:@"High Score"];
    
    [[NSUserDefaults standardUserDefaults] synchronize];



    SKTransition *reveal = [SKTransition fadeWithDuration:0.75];
    MGLCreateGameOverScene *scene = [MGLCreateGameOverScene sceneWithSize:self.view.bounds.size];
    scene.scaleMode = SKSceneScaleModeAspectFill;
    [self.view presentScene:scene transition:reveal];



移除剩余节点:

-(void)update:(CFTimeInterval)currentTime 
if (playerAlive == NO) 


    [self enumerateChildNodesWithName:@"obstacle" usingBlock:^(SKNode *node, BOOL *stop) 
        [node removeFromParent];
    ];


正如我之前所说,第一次玩时,记忆保持完全稳定。只有在第一次之后记忆开始上升。似乎您重温主要游戏场景的次数越多,内存攀升的速度就越快。我真的需要帮助来解决这个问题,我的游戏已经关闭了两个星期,我真的希望它恢复。感谢所有帮助。

【问题讨论】:

【参考方案1】:

你的问题在于这条线:

[self performSelector:@selector(createObstacle0) withObject:nil afterDelay:randomNum];

此方法实际上保留self(通过创建计时器)直到执行选择器之后。您需要做的是在更改场景之前将以下行添加到方法didBeginContact:

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(createObstacle0) object:nil];

这将破坏保留自身并无休止地调用该方法的计时器。

您可以通过在场景的 dealloc 方法中添加对 NSLog(@"%s", __PRETTY_FUNCTION__); 的调用来检查这是否有效。

【讨论】:

两周无意识的调整和研究,你刚刚解决了我的问题,非常感谢

以上是关于Spritekit 节点未从内存中删除的主要内容,如果未能解决你的问题,请参考以下文章

Sprite kit:删除特定节点而不是所有节点

Sprite Kit:删除底角的调试标签

iOS 7 Sprite Kit 释放内存

FPS在SpriteKit中下降

Swift:Spritekit 中的多个场景,从第二个和第一个场景的不同 Sprite 节点类型调用 touchesBegan

Sprite Kit,删除 Sprite 以进行碰撞