Leh*_*ves 20 memory-management physics game-physics ios sprite-kit
我正在构建一款针对新iOS 7和Sprite Kit的iOS游戏,使用发射器节点和物理来增强游戏性.在开发应用程序时,我遇到了一个严重的问题:您创建了场景,节点和效果,但是当您完成并需要返回主屏幕时,如何释放这些资源分配的所有内存?
理想情况下,ARC应该释放所有内容,应用程序应该恢复到创建场景之前的内存消耗级别,但这不是发生的事情.
我添加了以下代码,作为视图的dealloc方法,它绘制场景并负责在关闭(删除)后删除所有内容:
- (void) dealloc
{
if (scene != nil)
{
[scene setPaused:YES];
[scene removeAllActions];
[scene removeAllChildren];
scene = nil;
[((SKView *)sceneView) presentScene:nil];
sceneView = nil;
}
}
Run Code Online (Sandbox Code Playgroud)
我非常感谢你对此事的任何帮助.
Coc*_*ico 19
我在Sprite Kit中遇到了很多内存问题,我使用技术支持票来获取信息,这可能与此有关.我问的是,开始一个新的SKScene是否会完全释放前一个使用的所有内存.我发现了这个:
由+ textureWithImageNamed分配的底层内存:切换到新的SKScene时可能会或可能不会(通常不会)释放.你不能依赖它.iOS释放由+ textureWithImageNamed缓存的内存:或+ imageNamed:当它看起来合适时,例如当它检测到内存不足的情况时.
如果您希望在完成纹理后立即释放内存,则必须避免使用+ textureWithImageNamed:/ + imageNamed:.创建SKTextures的另一种方法是:首先使用+ imageWithContentsOfFile:创建UIImages,然后通过调用SKTexture/+ textureWithImage :( UIImage*)从生成的UIImage对象创建SKTextures.
我不知道这是否有帮助.
Lea*_*s2D 10
所有这些代码都是多余的.如果代码中没有内存泄漏或保留周期,一旦释放Sprite Kit视图,所有内容都将从内存中清除.
在引擎盖下Sprite Kit采用了缓存机制,但是我们无法控制它,我们也不需要它是否正确实现(可以安全地假设).
如果这不是您在仪器中看到的,请检查保留周期,泄漏.验证是否已调用场景和视图的dealloc.确保没有对视图,场景或其他节点的强引用保留在其他对象(特别是单例和全局变量)中.
小智 8
经过几天的斗争后,事实上关键是:[sceneView presentScene:nil]; 或者对于Swift:sceneView.presentScene(nil)
这可以在viewDidDisappear中完成.如果没有这个,即使在被解雇之后,你的观点也将继续留在现场,亲爱的生活,并继续咀嚼记忆.
斯威夫特3:
根据我的个人经验,我在 Xcode 工具的帮助下解决了问题,首先是使用活动监视器立即向我显示了巨大的内存增加,而不是分配和泄漏。
但也有一个有用的方法,调试控制台与
deinit {
print("\n THE SCENE \(type(of:self)) WAS REMOVED FROM MEMORY (DEINIT) \n")
}
Run Code Online (Sandbox Code Playgroud)
这是查看是否deinit
每次要删除场景时都调用的另一个帮助。
你在你的类中从来没有对scene
或 的强引用parent
,如果你有任何人,你必须将它转换为弱引用,例如:
weak var parentScene:SKScene?
Run Code Online (Sandbox Code Playgroud)
协议也一样,你可以像这个例子一样使用属性将它声明为弱class
:
protocol ResumeBtnSelectorDelegate: class {
func didPressResumeBtn(resumeBtn:SKSpriteNode)
}
weak var resumeBtnDelegate:ResumeBtnSelectorDelegate?
Run Code Online (Sandbox Code Playgroud)
ARC 完成了我们需要的所有工作,但是,如果您认为自己忘记正确编写某些属性(初始化、块..),我也在调试阶段使用了一些这样的函数:
func cleanScene() {
if let s = self.view?.scene {
NotificationCenter.default.removeObserver(self)
self.children
.forEach {
$0.removeAllActions()
$0.removeAllChildren()
$0.removeFromParent()
}
s.removeAllActions()
s.removeAllChildren()
s.removeFromParent()
}
}
override func willMove(from view: SKView) {
cleanScene()
self.removeAllActions()
self.removeAllChildren()
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
13395 次 |
最近记录: |