How are you supposed to be conservative about memory usage in a NSViewController?

I'm trying to get my head around view lifecycle and the memory management related to it.

I am looking to improve my understanding while also asking for recommendations on the best approach.


Let's say we have a NSTabViewController with 2 childViewControllers.

One of them is a NSViewController with an NSTextView.


Here is how I think of it.


When the view (and the NSTextView as part of the view hierarchy) is removed or hidden (as part of a tab selection), I want to also discard the contents (i.e. string/textStorage) in the NSTextView.

When the view is added or about to become visible, I want to (potentially load) and set the contents in the NSTextView.


Looking at the viewWillAppear/viewWillDisappear methods, the former is is called when "the view is about to be added to the view hierarchy of the view controller" while the latter is also called when "The view is about to be hidden or obscured".


Effectively that means, there is a case (when the view gets hidden) where the viewWillAppear is not paired with the viewWillDisappear. Is that by design?


Since as developers, we are not expected to manage any of the memory related to the view hierarchy, does that also extend to any data related to the view hierarchy?


In other words, are we only supposed to implement viewWillAppear in order to set the data to the view and leave the rest?

If so, are you only supposed to respond to memory warnings when the system itself deems necessary to deal with "excesive" memory usage?

Replies

Here my answers and practice


In other words, are we only supposed to implement viewWillAppear in order to set the data to the view and leave the rest?

YES, and I sometimes also reload tableView here


are you only supposed to respond to memory warnings when the system itself deems necessary to deal with "excesive" memory usage?

YES, that's what I do

Thank you. Appreciate the response! Can you please clarify a few things, primarily for my own understanding. Have you reached to that conclusion by experience, observation and reading the documentation or is there more to it? e.g. explicitly been told by Apple in an official (WWDC) or unofficial context?

Yes, that's by experience and general conclusion: do not try to interfere with system calls (despite they create some side effect from time to time).


That's of course not an official Apple response, maybe some one from Apple could comment on this.

Thank you. I would very much like an Apple response. More so on the reasoning/thinking behind being conservative, aggressive with memory usage and if so, how to best approach it in AppKit.

It's unlikely you'll get any kind of official answer from Apple, because this is a question about how you "should" approach writing your app, and there's no one answer.


Regarding viewWill/DidAppear/Disappear, the expectation is that the "appear" and "disappear" will be called in matched pairs. I just tried it on a tab view controller, and I'm getting both a "disappear" (for the old tab) and an "appear" (for the new tab) when switching tabs. The asymmetry is just in the documentation.


Regarding memory usage, it's up to you how you decide to approach this. On macOS, it's not generally a problem to keep data around when associated with an existing view (or, more likely, view controller), regardless of whether it happens to be visible.


That's because the data can be written to VM storage on disk if necessary, and that's often going to be faster than re-creating the data.


The usual recommendation in this area is to wait until you can see a measurable performance problem, then look for a solution. Putting the solution in advance of the problem can result in wasted effort, a distorted app design and still a performance problem in actual usage. 🙂

In the past, have found Apple to be quite vocal on WWDC on how to approach development, even when it comes to “best practices”. Re the NSTabViewController, try a couple of iterations. In my experience there are times where, as far as I can tell, the view is not removed from the hierarchy hence viewWillAppear isn’t called. I’m happy if the answer is to not worry about it. I would like to hear it straight from the horse’s mouth.

It doesn't work both ways, though: if Apple gives you guidance, it's a good idea to follow it if possible (because they tend to do that to push you towards something that is going to change in the future), but it doesn't mean there's guidance for everything.


>> as far as I can tell, the view is not removed from the hierarchy hence viewWillAppear isn’t called


Note that there is no API contract (AFAIK) that the view is removed from the view hierarchy so "hence" is questionable. It does seem that appear and disappear are intended to be in matching pairs, and in the case of a tab view they appear to be intended to surround a change of tab (however that's achieved underneath), so I would tend to regard an unmatched appear or disappear as a bug.


In fact, if you can report a bug with a test case attached, the answer "is working as intended" would be the definitive answer you're looking for.