Why some Outlets are made strong references even tough the documentation specifies that outlets should be weak reference

StackOverflow https://stackoverflow.com/questions/21846943

  •  13-10-2022
  •  | 
  •  

Question

Hi I am a newbie to iOS programming. I know what a strong and weak reference is. But I get confused which type of reference to use when I have to deal with outlets. After going through the documentation which states that

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.

So what I understood after going through the above statement is that the Outlets that we create should typically be weak by default.

But while studying some tutorials I have come across the code where people have declared an outlet as strong reference. For example consider the following code :

@interface AboutViewController : UIViewController

@property (nonatomic, strong) IBOutlet UIWebView *webView;

@end

The code :

@property (nonatomic, strong) IBOutlet UIWebView *webView;

says that our AboutViewController has an UIWebView object.

But why we need a strong reference here for the UIView object?? As the document states shouldn't this be an weak reference ?

Also please explain in the documentation statement which I have quoted above what does the File’s Owner to top-level objects mean?.

I have gone through many of the similar questions on this website but none of them helped me to clear my doubt. So please help. Thanks in advance :)

Was it helpful?

Solution

What to use for non top level GUI elements - strong or weak - depends on how you are going to use their outlets. If you have a weak reference

@property (nonatomic, weak) IBOutlet UIWebView *webView;

then after calling method

[webView removeFromSupeview];

your webView will be nil and it will be impossible to restore UIWebView just by adding

[self.view addSubview:webView];

If this is appropriate for you - it is better to use weak because you will free webView's memory when you do not need it.

On the other hand, in case of a strong reference after

[webView removeFromSupeview];

webView will still have referenceCount > 0 and webView will be deallocated only if owner will free it explicitly

self.webView = nil;

or in the owner's

- (void)dealloc

together with the owner itself.

Usually there is no difference if you have static GUI. If you want to remove (not hide) some views add be able to add them later - strong references should be used.

Top level objects should be retained strong. Like

@property(nonatomic,retain) UIView *view;

in UIViewController.

OTHER TIPS

It usually doesn't hurt to use a strong reference in place of a weak one in the case of outlets like this. And in some cases, you do need a strong reference.

The idea is that something has to keep a strong reference to the object at all times or it could vanish. If the object is a view that is a subview of another view, then that superview will keep a strong reference to it and so you can use a weak reference. But, if you're going to do something else with that view, such as remove it from it's superview for some reason (maybe to reuse it elsewhere, or something), then you'll want to use a strong property so that there's always something holding it strongly.

Regarding the File Owner issue, that's because the top level object (most likely a view) does not have a superview holding on to it, so you need to use a strong property so that you're holding on to it.

The simple answer is that unless you are supporting iOS 5, outlets should always be strong.

The purpose of weak outlets was so that in iOS5, if the system unloaded the view controller's view to save memory, any outlets pointing to subviews would be automatically released.

In iOS 6 and later, the system never unloads the view controller's view (viewDidUnload is never called) because Apple found a way to release most of the memory used by a view without releasing the view itself.

Consequently, the outlets in a view controller will never normally need to be released until the view controller itself is released, at which point ARC will clean up all the outlets anyway.

So just use strong for all your outlets and you won't have to worry about obscure bugs or compiler warnings due to using the wrong reference type.

Quoting from Apple's Resource Programming Guide,

Each time you ask the NSBundle or NSNib class to load a nib file, the underlying code creates a new copy of the objects in that file and returns them to you. You need to ensure that you maintain the new object graph as long as necessary, and disown it when you are finished with it. You typically need strong references to top-level objects to ensure that they are not deallocated; 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.

In case of framework classes like UIViewController the top-level object for the NIB file is the view property. If you check in the documentation it is declared as retain(similar to strong).

@property(nonatomic, retain) UIView *view

So any subviews to this container view should be automatically owned by it. If you now declare these subview outlets as strong they will create a strong cycle and cause memory leaks when the framework tries to cleanup the container view. To avoid these strong cycles all subviews (or non top level objects) should be declared as weak properties.

When can you declare IBOutlet's as strong

Outlets should be changed to strong when the outlet should be considered to own the referenced object:

  • As indicated previously, this is often the case with File’s Owner—top level objects in a nib file are frequently considered to be owned by the File’s Owner.
  • You may in some situations need an object from a nib file to exist outside of its original container. For example, you might have an outlet for a view that can be temporarily removed from its initial view hierarchy and must therefore be maintained independently.

You need to check in your code if webView object qualifies for case2 as above. If not the tutorial has got this one wrong and it actually should be weak.

Hope that helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top