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 节点未从内存中删除的主要内容,如果未能解决你的问题,请参考以下文章
Swift:Spritekit 中的多个场景,从第二个和第一个场景的不同 Sprite 节点类型调用 touchesBegan