1

I'm reading Apple's document on Acquiring Foundational Programming skills. I've read that references should be weak to outlets that are not to top-level objects, if it is to a top level object like "a window, view, view controller, or other controller". In the mixer tutorial I see that the app delegate has:

@property (assign) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSTextField *textField;
@property (weak) IBOutlet NSSlider *slider;

It tells me certain classes like NSWindow use assign instead. Since objects without a strong reference are removed, I was wondering how the objects in the window - the slider, text field, etc., persist, since I don't write any code for them other than dragging some stuff for the outlets and methods for app delegate that contain weak references - perhaps its all in the xib file and I haven't learned enough yet to see any flaws in the question, but I imagine each element of the interface needs to persist.

jscs
  • 63,694
  • 13
  • 151
  • 195
SJWard
  • 3,629
  • 5
  • 39
  • 54

1 Answers1

1

When you instantiate a view that you built in the interface builder, Cocoa creates the entire view hierarchy for you: the top window contains the slider, the text field, the buttons, and so on; subviews contain other subviews, which may in turn contain their own subviews. Each level in the hierarchy has a strong reference to levels below it, all the way down to the lowest level children. Once you have an instance of your view, it is sufficient for you to hold a strong reference to the top one: all other views would remain referenced by their parent view, preventing their premature destruction.

Note that only view inside the hierarchy rooted at self.view will remain referenced. If you have other IB elements that are not referenced from self.view, they need to be strong references. Otherwise, views "inflated" from XIB would be released as soon as the method that instantiated them exists, because there is no strong reference to keep these views alive.

It is common to make weak references to elements of your view hierarchy other than the top one, to avoid unintended self-referencing loops in your view hierarchy.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Thanks! so am I right in thinking then that the `@property (assign) IBOutlet NSWindow *window;` is all that is needed to maintain the view then? – SJWard Nov 17 '13 at 00:59
  • @Ward9250 the only difference between `assign` and `weak` is that the latter is automatically turning to `nil` when the referenced objects gets deallocated. That property is not contributing to keep the view in memory at all. – Gabriele Petronella Nov 17 '13 at 01:02
  • @Ward9250 No, an `assign` is not enough: `assign` is like `weak`, but less safe. You need a `strong` reference from your view controller to your top-level window; the remaining ones could be `weak`. – Sergey Kalinichenko Nov 17 '13 at 01:05
  • @dasblinkenlight you kind of touched on this but I wanted to be more explicit: Only view hierarchies inside `self.view` will be retained, if you have IB elements that are not inside `self.view` they need to be strong references, because once the view is inflated, there is no strong reference to keep them alive. – cream-corn Nov 17 '13 at 01:23
  • @cream-corn Thanks for a comment - I edited the answer to reflect this point. – Sergey Kalinichenko Nov 17 '13 at 01:28
  • @daskenblight I might be mistaken, but I only have the (assign) property that references the window in the code in my .h and .m files for app delegate (which I think it says here is the view controller unless I'm mistaken). – SJWard Nov 17 '13 at 02:14
  • @Ward9250 Your `NSViewController` has a `view` property that holds a strong reference to the top-level view of your view hierarchy. – Sergey Kalinichenko Nov 17 '13 at 02:16