Swift SpriteKit ARC for dummies

孤人 提交于 2019-12-01 11:47:49
crashoverride777

Thank you for all the answers, especially appzYourLift and your detailed reply.

I was digging into my spriteKit project the whole day, also experimenting with playground a lot and my game is totally leak free now with no strong reference cycles to be found.

It actually turned out a lot of the leaks/persistant classes I was seeing in instruments where simply there because something else didnt deallocate.

Its seems that repeat action forever was causing my leaks. All I had to do is loop through all the nodes in my scene and remove their actions.

This question helped me with this

iOS 7 Sprite Kit freeing up memory

UPDATE: I recently revisited this topic again because I felt like having to manually remove actions on nodes should not be necessary and could become cumbersome. After more research I found the precise issue for the (my) memory leaks.

Having a "SKAction repeat forever" like this apparently causes the leak.

let action1 = SKAction.wait(forDuration: 2)
let action2 = SKAction.run(someMethod) 
let sequence = SKAction.sequence([action1, action2])
run(SKAction.repeatForever(sequence))

So you need to change it to this to not cause a leak

 let action1 = SKAction.wait(forDuration: 2)
 let action2 = SKAction.run { [weak self] in
     self?.someMethod()
 } 
 let sequence = SKAction.sequence([action1, action2])
 run(SKAction.repeatForever(sequence))

This is coming directly from an Apple bug report I made.

Do all properties create strong reference cycles or only global properties that are created before a class is initialised?

Every strong reference to an object could become part of strong reference cycles. It could be

  1. a strong stored property
  2. a strong local/global variable/constant

With strong I mean it is not declared as weak or unowned.

Infact if for a given moment there is a strong reference path from an object to the object itself then the cycle is created and ARC will not free the memory for all the objects in the cycles.

What other things could potentially create a strong reference cycle in my simple classes?

There's no more to say. When the object A has a strong reference to the object B... which has a strong reference to A you have a strong reference cycle.

A few suggestions:

Keep track of the deinitialization

Just add a deinitializer to your class and check on the console that your objects do get deinitialized when you expect it

class Foo: SKSpriteNode {
    deinit {
        print(String(self))
    }
}

Let SpriteKit manage the strong references

Avoid strong references between nodes in your scene graph. Use instead the methods and computed properties provided by the SKNode class to retrieve other nodes like.

.scene
.parent
.childNodeWithName(...)
.childrean

This approach could lead to some performance issue but you should first make you code correct and then try to improve the performance.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!