即使调用removeAllChildren,SpriteKit中的内存也会增加 [英] Memory Increase in SpriteKit even though removeAllChildren called

查看:108
本文介绍了即使调用removeAllChildren,SpriteKit中的内存也会增加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经尝试修复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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆