3

Fairly straightforward question in two parts.

  1. If a view retains its subviews, and we create a view hierarchy in Interface Builder where views are nested within others, why does the IBOutlet property for the nested subviews need to be set to retain? Wouldn't assign be an acceptable parameter for those subview properties?

  2. I have a UIView subclass which adds a few subviews to itself upon initialization. To capture references to specific subviews, @property (nonatomic, assign) will suffice for that need, correct? For example, the main UIView adds a player score subview, then later wants to talk to that player score to update it. That reference only needs to be assigned, as the view proper is automatically retain by the UIView class, right?

christopherdrum
  • 1,513
  • 9
  • 25

2 Answers2

2

1) It doesn't need to be. assign is fine. What made you think that you have to use retain?

2) Yes

By the way, are you using ARC? If so, use weak instead of assign (please don't ask why, it is well explained in every corner of stack overflow and the Internet in general).

borrrden
  • 33,256
  • 8
  • 74
  • 109
  • The current project isn't ARC, so that was why I phrased the question specifically in the context of retain/assign. Thank you for thinking to confirm weak/strong with me. I didn't think I had to use retain, but I realized I'd gotten into a habit of doing that and couldn't explain why. As I started questioning myself I realized I needed confirmation from the community at large. On the other hand, I feel developers are constantly told (via online tutorials, for example) to release IBOutlets, which implies a retain, which has the reverse implication that one must always retain every IBOutlet. – christopherdrum Feb 18 '13 at 05:35
  • Any online tutorial that tells you to *always* release something should not be trusted. Any *retained* property must be released, just as any retained IBOutlet must. IBOutlets can be used for other things besides views, and if it is a top level object it will be deallocated immediately without being a retain property. – borrrden Feb 18 '13 at 05:39
1

Yes, it is true that in your case the subview will be retained by the view, so we don't technically need to retain it again. However, that is kind of fragile. What if in the future you add some code that removes that subview from its superview? Then you have a dangling pointer unless you make sure to nil it out.

It is general convention to retain instance variables, unless it is necessary not to (e.g. for delegates). If we go down the path of saying "oh we don't need to retain this instance variable because it's retained here; oh we do need to retain this other one because it's not retained; etc.", then we end up with very haphazard memory management, where every time we add an instance variable, we have to go and think about whether it is retained by something else or not; and then every time we use it, we have to remember whether we decided to retain it or not. It is precisely the kind of memory management nightmare that the memory management rules are designed to avoid.

And retaining the instance variable, what harm does it do? In this case, it just causes an additional retain and release when we assign it. Not a big deal, for the benefit of simplicity and consistency.

newacct
  • 119,665
  • 29
  • 163
  • 224
  • "think about whether it is retained by something else or not" I would humbly argue that this is exactly what we should be thinking about. In fact the Apple documentation pointed to in a link above explicitly recommends to keep weak references to IBOutlets that are not at the top level of the object retain hierarchy. – christopherdrum Feb 19 '13 at 03:53