即使调用removeAllChildren,SpriteKit中的内存也会增加 [英] Memory Increase in SpriteKit even though removeAllChildren called
问题描述
我已经尝试修复SpriteKit大量的内存增加了很多星期了,但是没有找到解决方案.我几乎尝试过网上遇到的用于在SK中管理内存的所有方法,但仍然遇到麻烦.这是我的情况:
I've been trying to fix a huge memory increase in SpriteKit for many weeks now but have found no solution. I have tried just about every method that I've come across online for managing memory in SK but am still having troubles. Here's my situation:
我首先展示SKScene"HomeScreen",然后从那里开始在View Controller中使用UIButton更改Page场景:
I first present the SKScene "HomeScreen" and from there I am changing Page scenes with a UIButton in my View Controller like so:
func nextPage(sender: UIButton) {
pageNumber = pageNumber + 1
let switchPage = SKTransition.crossFadeWithDuration(3.0)
switchPage.pausesOutgoingScene = false
switch pageNumber {
case 1: self.skView.presentScene(Page01(size: (self.view?.bounds.size)!), transition: switchPage)
case 2: self.skView.presentScene(Page02(size: (self.view?.bounds.size)!), transition: switchPage)
case 3: self.skView.presentScene(Page03(size: (self.view?.bounds.size)!), transition: switchPage)
case 4: self.skView.presentScene(Page04(size: (self.view?.bounds.size)!), transition: switchPage)
case 5: self.skView.presentScene(Page05(size: (self.view?.bounds.size)!), transition: switchPage)
case 6: self.skView.presentScene(Page06(size: (self.view?.bounds.size)!), transition: switchPage)
case 7: self.skView.presentScene(Page07(size: (self.view?.bounds.size)!), transition: switchPage)
case 8: self.skView.presentScene(Page08(size: (self.view?.bounds.size)!), transition: switchPage)
case 9: self.skView.presentScene(Page09(size: (self.view?.bounds.size)!), transition: switchPage)
case 10: self.skView.presentScene(Page10(size: (self.view?.bounds.size)!), transition: switchPage)
case 11: self.skView.presentScene(Page11(size: (self.view?.bounds.size)!), transition: switchPage)
default:
break
}
}
这是我从Xcode获得的内存图:
And here is my memory graph from Xcode:
如您所见,我对HomeScreen(HS)的内存从38.1开始,到我循环浏览所有场景并回到Home Screen时,它在112结束.我还分别加载了每个页面并记录了记忆以确认增加.
As you can see, my memory for HomeScreen (HS) starts at 38.1 and by the time I have cycled through all the scenes and come back to the Home Screen it ends at 112. I also loaded each page individually and recorded the memory to confirm the increase.
在每个SKScene中,我加载各种对象,然后在willMoveFromView中按如下方式删除它们:
In each SKScene, I load various objects and then in willMoveFromView I am removing them as so:
override func willMoveFromView(view: SKView) {
//Remove the Scroller Components
self.view?.removeGestureRecognizer(self.page01Drops.panGestureRecognizer)
self.page01Drops = nil
//Remove Environment
self.randomObjectFromScene.texture = nil
self.anotherRandomObject.removeFromParent
self.removeAllActions()
self.removeAllChildren()
}
更多信息: -场景更改后未调用Deinit.
Here's a little more info: - Deinit is not being called after a scene changes.
-
使用Instruments测试应用程序时没有泄漏.
I have no leaks when testing the app with Instruments.
首先使用stringByAppendingPathComponent将所有SKTextures作为UIImage加载.
All SKTextures are loaded first as UIImages using stringByAppendingPathComponent.
所有willMoveFromView方法都包含removeAllActions和removeAllChildren.
All willMoveFromView methods contain removeAllActions and removeAllChildren.
有人知道为什么我的记忆力在增加吗?
Does anyone know why my memory is increasing?
更新更多示例代码
这是我如何在viewDidLoad中加载skView:
Here is how I load my skView in viewDidLoad:
skView = view as! SKView
skView.showsFPS = true
skView.showsNodeCount = true
skView.ignoresSiblingOrder = false
skView.presentScene(homeScreen(size: skView.bounds.size))
以下是我的Page01 SKScene的一些内容:
And here is a bit from my Page01 SKScene:
class Page01: SKScene {
//Preload Textures
let aaronHead01Texture = SKTexture(image: UIImage(contentsOfFile:NSBundle.mainBundle().resourcePath!.stringByAppendingPathComponent("P01_head01.png"))!)
let aaronHead02Texture = SKTexture(image: UIImage(contentsOfFile:NSBundle.mainBundle().resourcePath!.stringByAppendingPathComponent("P01_head02.png"))!)
//more textures for body parts of character that will be changed
var aaronHead: SKSpriteNode!
//More SKSpriteNodes for other body parts
override init(size: CGSize){
super.init(size: size)
self.aaronHead = SKSpriteNode(texture: self.aaronHead01Texture)
self.aaronHead.anchorPoint = CGPoint(x: 0.5, y: 0.1)
self.aaronHead.position = CGPoint(x: 10, y: 284)
self.aaronHead.zPosition = 1.0
self.aaronBody.addChild(aaronHead)
}
推荐答案
您已经发现了问题:
场景更改后未调用Deinit.
Deinit is not being called after a scene changes.
如果scene
确实发生了变化,则不调用旧场景的deinit
,那就是问题所在.这意味着旧场景仍在内存中.
If when a scene
does change the deinit
of the old scene is not called then that's the problem. It means that the old scene is still in memory.
这可能是由于您的保留周期强而发生的.这意味着您场景中的一个孩子(或一个孩子中的一个孩子...)对场景本身有强引用.
This is probably happening because you have a strong retain cycle. This means that a child (or a child of a child...) of your scene has a strong reference to the scene itself.
您必须找到该引用并使用weak
关键字对其进行声明.
You must find that reference and declare it with the weak
keyword.
这篇关于即使调用removeAllChildren,SpriteKit中的内存也会增加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!