Ios 如何完全卸载SpriteKit场景

Ios 如何完全卸载SpriteKit场景,ios,sprite-kit,skscene,skview,Ios,Sprite Kit,Skscene,Skview,当我在游戏中点击重试按钮时,我希望它重新加载主场景。我是这样做的: -(void)retry { SKTransition *transition = [SKTransition fadeWithDuration:.4]; MainScene *gameOver = [[MainScene alloc] initWithSize:self.size]; [gameOver didMoveToView:self.view]; [self.scene.view pre

当我在游戏中点击重试按钮时,我希望它重新加载主场景。我是这样做的:

-(void)retry
{
    SKTransition *transition = [SKTransition fadeWithDuration:.4];
    MainScene *gameOver = [[MainScene alloc] initWithSize:self.size];
    [gameOver didMoveToView:self.view];
    [self.scene.view presentScene:gameOver transition:transition];
}
但是,这会导致每次单击“重试”时内存/CPU使用率增加(很多)。在大约10-20次重试后,会出现明显的延迟

我将所有的SKEmitterNode和SKSpriteNode设置为静态,这修复了内存问题,因此我怀疑我的精灵、发射器等没有从内存中释放出来,并且在每次单击“重试”时都会重新加载,使其加倍

我正在加载精灵/发射器,如下所示:

@implementation MainScene {
    SKEmitterNode *_bubbleEmitter;
    SKSpriteNode *_sunglasses;
    ...
}

- (id)initWithSize:(CGSize)size
{
  if (self = [super initWithSize:size]) 
  {
     _sunglasses = [SKSpriteNode spriteNodeWithImageNamed:@"sunglasses"];
     [_sunglasses setPosition:CGPointMake(self.size.width/2,  self.size.height + 10)];
     [self addChild:_sunglasses];

     ...
  }
  return self;
}

是否加载精灵或重试错误?

这可能是原因,也可能不是原因,但自己调用此方法肯定是错误的:

[gameOver didMoveToView:self.view];
演示场景时,SKView会将
didMoveToView:
方法发送到场景。这意味着该方法将实际运行两次

还可以通过实现以下功能来验证场景是否正确解除分配:

-(void) dealloc
{
    NSLog(@"dealloc: %@", self);
}

观察日志或设置断点以确认场景解除分配。如果不是,请检查内存泄漏和保留周期。

@ElTomato是的,我想了,但我不确定要更改什么。我不知道为什么会有这些代码,可能是通过测试不同的东西。Dealloc没有接到电话,但我不知道为什么。有一个微小的内存泄漏,但它与CGPath有关,我读到的只是physicsbody的一个bug。是否还有其他原因导致dealloc可能未被调用?请保留循环,检查对场景的任何强引用,以及保留对父节点或同级节点的强引用的任何节点(这些节点应为弱节点)。此外,您创建的CGPath对象在使用/分配后也必须是cgpathlease(path),这可能不是Sprite Kit的问题。宾果!结果表明,NSTimer仍在运行,需要失效。正在调用Dealloc,问题已解决。好吧,差不多了,似乎还有一个小内存泄漏,但主要问题已经解决了:)谢谢!不要将NSTimer用于精灵套件中任何与计时相关的东西!使用场景的更新方法。NSTimer可能在更新循环中的不确定时间触发,而且如果暂停/转换节点或场景,它们不会暂停。在iOS 8中,使用Swift实现,我在模拟器中发现问题发生在SpriteKit场景没有完全卸载。但当我在真实设备上测试时,并没有这样的问题。