10

Do I still need to set IBOutlet properties to null in viewDidUnload with ARC?

Because it still generates the following comment:

// Release any retained subviews of the main view.

TheLearner
  • 19,387
  • 35
  • 95
  • 163
  • 4
    possible duplicate of [IBOutlet and viewDidUnload under ARC](http://stackoverflow.com/questions/7682322/iboutlet-and-viewdidunload-under-arc) – jscs May 17 '12 at 16:33

3 Answers3

13

Well the main purpose of nilling outlet it was to do not create zombies, leaks and weird situations that could happen when the subviews have not a super view, while the view was unloaded from the view controller.

Now with the latest version of Xcode if you drag a view element inside a header or in a private declaration it sets automatically the Outlet to weak (targeting iOS>=5) and also in the viewDidUnload method it will write [self setYourOutlet:nil]; probably in this case is not necessary, but is a good practice. If you target lower ioses is needed, because you can't use weak reference. I suggest to use always because is a good habit.

UPDATE

I'd like to complete the answer to avoid misunderstandings (talking about iOS5 only) pay attention that IB sets outlet to weak only if the are subviews of a main view. Typically it happens in a xib containing a view from a view controller.

Sometimes could happen that you need to swap two views based on some condition at runtime without creating them programmatically or in different xibs. For instance you have your main view owned by the vc, and in the same xib you create two other views that in that moment doesn't have a superview. If you try to connect them with the same technique the reference created will be strong. At runtime you can then now swap the views simply adding or removing from the superview of course you should nil them in viewDidUnload.

Andrea
  • 26,120
  • 10
  • 85
  • 131
  • Why do you consider the following good practice ; '[self setYourOutlet:nil]; probably in this case is not necessary, but is a good practice' ? – Ríomhaire May 02 '13 at 13:17
  • @Ríomhaire well, imagine that you need to lower the deployment target to 4.3, in this case you will only need to change weak to unsafe_unretained – Andrea May 02 '13 at 13:29
11

I'll expand on Andrea's answer here (upvote him!) because the answer isn't straight forward unless you only mean UI components, in which case they should all be weak.

IBOutlets are whatever you define them. If you use:

@property (nonatomic, strong) IBOutlet UIView *someView;

You should nil this when unloading the parent view/window.

If you do:

@property (nonatomic, weak) IBOutlet __weak UIView *someView;

You don't have to nil the variable, because it will be auto zero'ed.

How you nil is entirely up to you. Prior to ARC I used:

[someView_ release], someView_ = nil;

Now you have two options: either use the setter (created with with @synthesize) or set the underlying ivar directly. The result is the same - in both instances the object's lifetime qualifiers will note it's final use and release it.

So, go ahead and do this:

self.someView = nil

or

@synthesize someView = someView_;
...
someView_ = nil;
Matt Melton
  • 2,493
  • 19
  • 25
  • 4
    +1 This is the right answer. You must set strong references to `nil` in order to free up resources. There's no need to set weak references to `nil` because the compiler will do that for you if the resource is deallocated. – Caleb May 17 '12 at 16:33
  • I thought the compiler under ARC set *strong* properties to nil as well? – Hari Honor Nov 14 '12 at 18:01
  • It doesn't matter - you can't read it. Weak properties can become nil at any point during execution. When you *finally* use a locally scoped *object* you nil it (causing the compiler release it), if you continue to use it you can observe a nil value. Alternatively you can let the compiler release a locally scoped object for you when it's out of scope, but leaving scope implies a *final* use as you never observe the nil value. Strong *properties* are scoped to your class, therefore the implied release occurs in dealloc, after which you can't access the member either. – Matt Melton Nov 15 '12 at 10:18
2

For IBOutlets marked as strong you still do want to nil them out in viewDidUnload.

Why:

When you receive a low memory notification any views not currently visible may unload themselves (calling viewDidUnload) to save memory. By nilling out your outlets you are giving up ownership and letting them be released. When the view is loaded again (when it is shown again), the outlets will be setup again and viewDidLoad will be called.

Reese McLean
  • 88
  • 2
  • 9