Updating NSView With SubViews and a Memory Leak

I have an IBOutlet-wired NSView object named displayView, where I add 3 to 4 NSImageView objects as subViews. Whenever the user resizes the application window, this displayView guy needs to be updated. When the user closes the application window with the red close button, the application hides it with


NSApp.hide(nil)


. When the user clicks on the doc icon of the application, the application unhide the window. When it does, the application will remove all sub views like


for sub in displayView.subviews {
  sub.removeFromSuperview()
}


But the application leaks the memory a big time. If I repeat the sequence of hiding and unhiding the application window 5 to 6 times, its memory consumption can reach 500 MB. I know what to do, but my question is why the application keeps mounting its leak even though it removes its all sub views whenever the application is back to life from hiding itself and updates the displayView guy.


Muchos thankos.

Replies

That answer is obvious--it leaks because it's a guy.

Could you add some log:


print("Nb of subviews", displayView.subviews.count)
for sub in displayView.subviews {
  sub.removeFromSuperview()
}


And report what you get.

Claude,


The following code shows sub view counts.



class MainViewController: NSViewController {
    @IBOutlet weak var displayView: NSView!
 
    override func viewWillAppear() {
        super.viewWillAppear()
     
        print("No. of subviews before the display view shows up", displayView.subviews.count) // => 0
        for sub in displayView.subviews {
            sub.removeFromSuperview()
        }
    }
 
    override func viewDidAppear() {
        super.viewDidAppear()
     
        for sub in displayView.subviews {
            sub.removeFromSuperview()
        }
        print("No. of subviews after the display view shows up", displayView.subviews.count) // => 0
    }
 
    override func viewWillDisappear() {
        super.viewWillDisappear()
     
        print("No. of subviews right before the display view hides itself", displayView.subviews.count) // => 3
        for sub in displayView.subviews {
            sub.removeFromSuperview()
        }
    }
 
    override func viewDidDisappear() {
        super.viewDidDisappear()
     
        print("No. of subviews after the display view hides itself", displayView.subviews.count) // => 0
    }
}



Initially, the memory consumption stays around 100 MB. After I hide the window and bring it back five times or so, it will go up to around 480 MB.

In this code, we only see views being removed, never added.


Line 16: why do you remove when viesDidAppear (is is just for testing purpose ?)


Where are subviews added ?

What is the size of NSImageView ? Is it a few 100 kB or in the 10 MB to 20 MB?

If the later, probably you reload a new copy of the images in memory.

Where do you inspect the memory used ? In XCode debug session ? Did you look at it with instruments ?


May also have a look here: https://developer.apple.com/documentation/xcode/improving_your_app_s_performance/reducing_your_app_s_memory_use/gathering_information_about_memory_use