I make a bunch of sprites from the gameScene and other objects, all by calling a function that creates instances of a subclass of SKSpriteNode.
eg, from GameScene, like this:
let sizee = CGSize(width: 100, height: 100)
let posi = CGPoint(x: 200, y: 300)
func createSprite(){
let new = Circle(color: SKColor.blue, size: sizee , position: posi)
addChild(new)
new.zPosition = 2
}
from within Circle, I remove each instance after its done a bit of animating:
import SpriteKit
class Circle: SKSpriteNode {
let fade = SKAction.fadeAlpha(to: 0.5, duration: 2)
let myScale = SKAction.scaleX(to: 3, duration: 2)
let die = SKAction.removeFromParent()
override init(texture: SKTexture?, color: UIColor, size: CGSize) {
super.init(texture: texture, color: color, size: size)
}
convenience init(color: UIColor, size: CGSize, position: CGPoint) {
self.init(color: color, size: size)
self.position = position
self.run(SKAction.sequence([fade, die]))
self.run(myScale)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Is this enough to ensure that these are getting released from memory?
Or do I have to do something else to flush them from the game world and memory?
Few weeks ago Apple have update this page:
Swift uses Automatic Reference Counting (ARC) to track and manage your app’s memory usage. In most cases, this means that memory management “just works” in Swift, and you do not need to think about memory management yourself. ARC automatically frees up the memory used by class instances when those instances are no longer needed.
Reference counting only applies to instances of classes. Structures and enumerations are value types, not reference types, and are not stored and passed by reference.
There is a way to prevent an instance from deinitialising, and thus creating a leak. This is called a Strong Reference Cycle. Take a look at this answer where you can understand in detail what I mean now.
Looking to your code I would have done this:
self.run(SKAction.group([fade, myScale], completion: {
[weak self] in
guard let strongSelf = self else { return }
strongSelf.removeFromParent()
}))
Yes, I think so.
There is basically one thing that you need to do to check whether something's memory will be released:
Check if there are any other objects which hold strong references to the object that you're checking.
In this case, you want to check whether your Circles will be released from memory. Let's see what objects strongly reference Circle, starting from the creation of a circle.
When the circle is created, the new variable holds a strong reference. This reference will break after the method createSprite returns.
When the circle is added to the scene, the scene holds a strong reference to the circle. This reference will be broken after the circle is removed from the scene.
Other than those, I can't see any other strong references to the circle object. So you should be fine.
Also, in Xcode 8, there's a new memory debugging feature. You can use it to check this too!
Just run your app, and click this:

Then go to the main editor area, you should see this ("TestingArea" is the name of my app):

Now you can see all the instances of the objects you created by clicking on the button which is on the right of your app's name. In my case, it's the button on the right of "TestingArea" i.e. "AppDelegate":

If you see Circle in that list, that means your app has a Circle object somewhere. If not, no Circle is in memory!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With