如何释放未使用的 SKScene

Posted

技术标签:

【中文标题】如何释放未使用的 SKScene【英文标题】:How to deallocate unused SKScene 【发布时间】:2016-02-14 05:24:02 【问题描述】:

我在 GameViewController 中有一个 SKScene 对象设置。我在 SKScene 子类中实现了dealloc,如下所示:

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

现在我想在 GameViewController 之上展示另一个视图控制器。我使用故事板segue来做到这一点。但是在新的视图控制器出现后,我再也没有收到 SKScene dealloc。它卡在了记忆里。由于内存不足,我的应用程序在几分钟后开始冻结。呈现新的视图控制器后如何解除场景的分配。

【问题讨论】:

@user3351949 我这样做了:SKView *skView = (SKView *)self.view; [skView presentScene:nil]; 不起作用。 @user3351949 现在我这样做了:SKView *skView = (SKView *)self.view; GameScene *scene = (GameScene *)skView.scene; [skView presentScene:nil]; scene = nil; 仍然不起作用 您在另一个 ViewController 之上展示了一个 ViewController....当您展示下一个 VC 时,前一个 VC 不会被解除分配......您有一个导航堆栈在这里重新创建它引用了堆栈中的所有内容。如果在从堆栈中删除前一个 VC 时呈现您呈现的内容......那么您就是 VC,只要没有其他内容包含对它们的强引用,它的各自视图(SKView)就会被释放。 【参考方案1】:

为了释放你 SKScene 实例 -> 你应该消除每个保留它的指针 -> 然后 ARC 会自动释放它。

只需调用[skView presentScene:nil]; 方法,该方法也将删除SCScene 并通过将SKView.scene 属性设置为nil 来释放它。

SKView *skView = (SKView *)self.view; 
GameScene *scene = (GameScene *)skView.scene; 

for(SKNode * child in scene.children)

    [child removeAllActions];

[scene removeAllChildren];
[scene removeAllActions];
[skView presentScene:nil]; 

注意 通常你不必从SKScene 中删除所有内容,如果你的内存管理正确,只需调用[skView presentScene:nil]; 方法,ARC 会处理它。

显然您在SKScene 中保留了它。 因此,通过从中删除所有内容,我们消除了保留周期。

此解决方案并不总是有效,仅当 SKActionsSKNodes 之一保留 SKScene 时才有效,这是您的问题,但是您的 SKScene 可以保留从其他地方,这个答案不会真正帮助你

【讨论】:

我打电话给[scene removeFromParent];,还是不行。 GameScene 上的 NSLogdealloc 方法由于某种原因仍然没有被调用。内存似乎没有被释放。 检查也许你有一个强指针循环 -> 这个方法应该真的有效。 哦,也许你还有一些动作?尝试删除所有操作我将发布代码 sn-p。请尝试一下。如果它不起作用,那么我建议使用 Allocations 在 Instruments 中进行配置 我用[scene removeAllAction];还是不行,可能是苹果私有API中有一个指针阻止场景释放

以上是关于如何释放未使用的 SKScene的主要内容,如果未能解决你的问题,请参考以下文章

如何列出所有未使用的弹性IP并使用boto3释放它们

如何列出所有实时(未释放)的 UIViewControllers?

如何恢复未释放租约的HDFS文件

如何解决 C++ 中的未释放锁问题

如何解决Linux系统文件已删除但空间未释放

ARC 和dismissModalViewControllerAnimated:视图控制器内存未释放