开发者

Loading UIImage's on background thread solves SceneKit memory problems. Why?

Consider the following code:

let img = UIImage(named: "myString")
if let img = img {
    mySCNMaterial.diffuse.contents = img    
}

I was using this to load images in a SceneKit project. Specifically, I was doing this from inside my UIViewController's viewDidLoad.

As long as I was doing it this way, my project was leaking memory like crazy (restarting a level in the game would bump memory consumption up by something like 30mb each time, and that memory would never be reclaimed). However, Instruments found no memory leaks, and enabling my project scheme's Zombie Objects gave results that were...literally unbelievable, with something like 1000+ zombies from all kinds of sources.

At some point, I learned about the difference between UIImage(named:) and UIImage(contentsOfFile:), with the system caching the former, but not the latter.

So, now I've got this:

let path = Bundle.main.path(forResource: "myString", ofType: "png")!
let img = UIImage(contentsOfFile: path)!
mySCNMaterial.diffuse.contents = img

I theorized that this would improve memory usage in my own game, but the gains were minimal at best.

But today I decided to try explicitly running the previous bit of code on a background thread (UIImage is thread-safe, according to the documentation) -- and my game stopped leaking memory entirely, as determined by the Instruments Allocations template.

So, now I've got this:

DispatchQueue.global(qos: .background).async {
    let path = Bundle.main.path(forResource: "myString", ofType: "png")!
    let img = UIImage(contentsOfFile: path)!
    mySCNMaterial.diffuse.contents = img
}

While I'm very glad to have stumbled upon this fix, I'd开发者_Go百科 like to better understand what's going on.

Question: Why might these changes solve my SceneKit game's memory usage problems?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜