如何正确地释放一组继承自 SKSpriteNode 的对象
How to properly deallocate a Set of objects that inherit from SKSpriteNode
我想知道解除分配从 SKSpriteNode 继承的 Set 对象的最佳方法是什么。我有以下代码:
class Raindrop : SKSpriteNode
{
weak var barSpriteRef: SKSpriteNode?
init(scene: SKScene, barSprite: SKSpriteNode)
{
let texture = SKTexture(imageNamed: "RainDrop")
super.init(texture: texture, color: SKColor.whiteColor(), size: texture.size())
barSpriteRef = barSprite
self.userInteractionEnabled = true
let width = scene.view!.frame.width
let randomPos = CGPointMake(CGFloat(arc4random()) % width, UIScreen.mainScreen().bounds.height + 50)
self.position = randomPos
self.zPosition = 1
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
scene.addChild(self)
let moveDown = SKAction.moveToY(-UIScreen.mainScreen().bounds.height, duration: 8)
self.runAction(moveDown)
}
required init?(coder aDecoder: NSCoder)
{
fatalError("init(coder:) has not been implemented")
}
func kill()
{
self.removeAllActions()
self.removeFromParent()
}
}
函数 kill() 是我尝试解除分配的尝试,但它没有按预期工作。
我正在使用这样的集合:
var raindrops = Set<Raindrop>()
ARC 的工作原理
ARC 会在内存中保留被强引用的对象。
SpriteKit
这在 SpriteKit
中也是如此,事实上每个被 GameScene
强烈引用的节点(或被 GameScene
... 引用的节点引用)都保存在内存中。
你做的是正确的(但可能还不够)
您正在尝试使用您的 kill
方法解除分配您的 Raindrop
精灵
func kill() {
self.removeAllActions()
self.removeFromParent()
}
此方法有效如果 当前 Raindrop
仅由其父级和某些操作引用。
但是,如果您在另一个节点中创建了这个 Set
var raindrops = Set<Raindrop>()
然后将您的 sprite 添加到 Set
,您创建了另一个 strong reference,它将在内存中保留您的 Raindrop
sprite。
例子
让我们定义一个 GameScene 和一个 Hero 节点。
class GameScene: SKScene {
deinit { print("GameScene has been deallocated") }
}
class Hero: SKNode {
deinit { print("Hero has been deallocated") }
}
The deinit
will print a message into the console as soon as the object is deallocated
现在让我们看一下这段代码
let scene = GameScene(size: CGSize(width: 100, height: 100))
var hero: SKNode? = Hero()
var set = Set<SKNode>([hero!])
scene.addChild(Hero())
Hero 对象有 3 个强引用
- 来自
scene
hero
变量
set
变量
让我们删除前 2 个引用
hero?.removeFromParent()
hero = nil
英雄仍然在记忆中,因为 set
.
强烈引用
最后让我们运行
set.removeAll()
现在我们收到以下消息,因为 Hero 终于被释放了。
Hero has been deallocated
我想知道解除分配从 SKSpriteNode 继承的 Set 对象的最佳方法是什么。我有以下代码:
class Raindrop : SKSpriteNode
{
weak var barSpriteRef: SKSpriteNode?
init(scene: SKScene, barSprite: SKSpriteNode)
{
let texture = SKTexture(imageNamed: "RainDrop")
super.init(texture: texture, color: SKColor.whiteColor(), size: texture.size())
barSpriteRef = barSprite
self.userInteractionEnabled = true
let width = scene.view!.frame.width
let randomPos = CGPointMake(CGFloat(arc4random()) % width, UIScreen.mainScreen().bounds.height + 50)
self.position = randomPos
self.zPosition = 1
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
scene.addChild(self)
let moveDown = SKAction.moveToY(-UIScreen.mainScreen().bounds.height, duration: 8)
self.runAction(moveDown)
}
required init?(coder aDecoder: NSCoder)
{
fatalError("init(coder:) has not been implemented")
}
func kill()
{
self.removeAllActions()
self.removeFromParent()
}
}
函数 kill() 是我尝试解除分配的尝试,但它没有按预期工作。
我正在使用这样的集合:
var raindrops = Set<Raindrop>()
ARC 的工作原理
ARC 会在内存中保留被强引用的对象。
SpriteKit
这在 SpriteKit
中也是如此,事实上每个被 GameScene
强烈引用的节点(或被 GameScene
... 引用的节点引用)都保存在内存中。
你做的是正确的(但可能还不够)
您正在尝试使用您的 kill
方法解除分配您的 Raindrop
精灵
func kill() {
self.removeAllActions()
self.removeFromParent()
}
此方法有效如果 当前 Raindrop
仅由其父级和某些操作引用。
但是,如果您在另一个节点中创建了这个 Set
var raindrops = Set<Raindrop>()
然后将您的 sprite 添加到 Set
,您创建了另一个 strong reference,它将在内存中保留您的 Raindrop
sprite。
例子
让我们定义一个 GameScene 和一个 Hero 节点。
class GameScene: SKScene {
deinit { print("GameScene has been deallocated") }
}
class Hero: SKNode {
deinit { print("Hero has been deallocated") }
}
The
deinit
will print a message into the console as soon as the object is deallocated
现在让我们看一下这段代码
let scene = GameScene(size: CGSize(width: 100, height: 100))
var hero: SKNode? = Hero()
var set = Set<SKNode>([hero!])
scene.addChild(Hero())
Hero 对象有 3 个强引用
- 来自
scene
hero
变量set
变量
让我们删除前 2 个引用
hero?.removeFromParent()
hero = nil
英雄仍然在记忆中,因为 set
.
最后让我们运行
set.removeAll()
现在我们收到以下消息,因为 Hero 终于被释放了。
Hero has been deallocated