1
votes

I'm aware best practices for Objective-C development says IBOutlets should always be defined as properties according to Apple.

From a practical perspective, in iOS and OS X outlets should be defined as declared properties. Outlets should generally be weak, except for those from File’s Owner to top-level objects in a nib file (or, in iOS, a storyboard scene) which should be strong.

But for learning purposes let's say we got the following scenario using ARC:

#import <UIKit/UIKit.h>

@interface DetailViewController : UIViewController{
     IBOutlet UIButton *buttonA;
     IBOutlet UIButton *buttonB;
     IBOutlet UIButton *buttonC;
}

@end

If I'm not mistaken, those three buttons are strong, so my question is: Will those buttons be released from memory once the ViewController is released?

Those buttons would be released automatically if they were weak, I know that, but not sure if they are strong.

Can anyone please help? Just to be clear, the method 'dealloc' on DetailViewController is empty.

2
This ivars will be strong as you wrote. You should set them to nil in viewDidUnload. And call [super viewDidUnload] after that. But better way is to make @interface DetailViewController () in @implementation and there create properties for outlets.Tomasz Szulc
Thank you for your comment Tomasz. What if I don't set them to nil on viewDidUnload? Will I have an issue with the memory management? That's what I'm trying to find out. I've tried with instruments, but no leaks are pointed out...RGML
Before ARC it was important to set to nil, but it's not required any more. You won't get a leak. When an object is released, it's strong references are dissolved. So owned objects will be released.jbbenni
Note that (a) viewDidUnload is not called anymore; and (b) even when it was used, its sole purpose was handling the unloading of some views when memory warnings were received. So, handle viewDidUnload if you need backward compatibility and are worried about this special scenario in pre-ARC code using retain with its IBOutlet references. But when considering the basic object graph, viewDidUnload is not relevant.Rob
@TomaszSzulc In ARC, for normal strong objects, when the view controller is deallocated, all of the strong variables are automatically released, so no manual nil-ing of them is needed. (It's one of the joys of ARC.) In non-ARC code, you have to write your own dealloc method that manually performs release for all of those strong variables.Rob

2 Answers

4
votes

You asked:

If I'm not mistaken, those three buttons are strong, so my question is: Will those buttons be released from memory once the ViewController is released?

Yes. Or, more accurately, those buttons will be deallocated when there are no more strong references. And in this scenario, those buttons now have two strong references, one being the view controller and another being the view to which these buttons were added as subviews. Both of those strong references would need to be relieved before the button would be deallocated.

But why would you want to maintain two strong references to that control? Generally you let the view maintain the strong reference to its subviews (i.e. let the view "own" its subviews), and the view controller is only using a weak reference to those subviews.

Those buttons would be released automatically if they were weak, I know that, but not sure if they are strong.

When the view controller has the weak reference, the buttons are being released because the only strong reference to the button is maintained by its superview and when that view is removed, then the button will lose its last strong reference and can be deallocated.

If the view controller has a strong reference, you are unnecessarily added another strong reference that needs to be relieved before the buttons are deallocated. You can do that, but it's unnecessary. You quoted from the Resource Programming Guide, but the preceding sentence says "you don’t need strong references to objects lower down in the graph because they're owned by their parents, and you should minimize the risk of creating strong reference cycles."

Bottom line, your example with the implicitly strong references to the IBOutlet controls will work fine. But there's no advantage to having the view controller maintain a strong reference to the buttons and it represents a bit of a misunderstanding of the object graph. View controllers really should only be maintaining weak references to the controls on their views.

2
votes

Yes, when the ViewController is released, even its strongly referenced objects will be released. (Unless of course, some other non-released object holds a strong reference to them.)

There's a good discussion of weak and strong here: Explanation of strong and weak storage in iOS5