Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

weak or strong for IBOutlet and other [duplicate]

I have switched my project to ARC, and I don't understand if I have to use strong or weak for IBOutlets. Xcode do this: in interface builder, if a create a UILabel for example and I connect it with assistant editor to my ViewController, it create this:

@property (nonatomic, strong) UILabel *aLabel;

It uses the strong, instead I read a tutorial on RayWenderlich website that say this:

But for these two particular properties I have other plans. Instead of strong, we will declare them as weak.

@property (nonatomic, weak) IBOutlet UITableView *tableView;
@property (nonatomic, weak) IBOutlet UISearchBar *searchBar;

Weak is the recommended relationship for all outlet properties. These view objects are already part of the view controller’s view hierarchy and don’t need to be retained elsewhere. The big advantage of declaring your outlets weak is that it saves you time writing the viewDidUnload method.

Currently our viewDidUnload looks like this:

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.tableView = nil;
    self.searchBar = nil;
    soundEffect = nil;
}

You can now simplify it to the following:

- (void)viewDidUnload
{
    [super viewDidUnload];
    soundEffect = nil;
}

So use weak, instead of the strong, and remove the set to nil in the videDidUnload, instead Xcode use the strong, and use the self... = nil in the viewDidUnload.

My question is: when do I have to use strong, and when weak? I want also use for deployment target iOS 4, so when do I have to use the unsafe_unretain? Anyone can help to explain me well with a small tutorial, when use strong, weak and unsafe_unretain with ARC?

like image 332
Piero Avatar asked Jun 23 '12 10:06

Piero


People also ask

Should IBOutlet be strong or weak?

The official answer from Apple is that IBOutlets should be strong. The only case when an IBOutlet should be weak is to avoid a retain cycle. A strong reference cycle can result in memory leaks and app crashes.

Why We Use weak in IBOutlet Swift?

@IBOutlet makes Interface Builder recognize the outlet. private ensures the outlet isn't accessed outside the current class. weak is used because in most situations the owner of the outlet isn't the same as the owner of the view. For example, a view controller doesn't own someLabel - the view controller's view does.

What is IBOutlet weak VAR?

In Mac development an IBOutlet is usually a weak reference: if you have a subclass of NSViewController only the top-level view will be retained and when you dealloc the controller all its subviews and outlets are freed automatically. UiViewController use Key Value Coding to set the outlets using strong references.

What is the difference between IBOutlet and IBAction?

An IBOutlet is for hooking up a property to a view when designing your XIB. An IBAction is for hooking a method (action) up to a view when designing your XIB. An IBOutlet lets you reference the view from your controller code.

Should I use strong or weak for outlets?

Apple suggests always using Strong over Weak unless your outlet references the owning object strongly. For example, if you have a UIViewController containing a custom UIView as an outlet, and this view has a strong reference to the view controller, you must use Weak to not introduce a memory leak.

What is a good example of a strong and weak property?

A good example is the delegation design pattern, where we have the first view controller stored as a weak property inside the second view controller. Now that you have an idea of what strong and weak means, it’s time to decide what storage type to use when working with @IBOutlets.

Should outlets be strong or weak in iOS 14?

Yes, previously outlets should generally be weak but Apple has changed that. Now they recommend to use strong outlets in the WWDC 2015 session Implementing UI Designs in Interface Builder.

When should I use strong vs weak in UIViewController?

For example, if you have a UIViewController containing a custom UIView as an outlet, and this view has a strong reference to the view controller, you must use Weak to not introduce a memory leak. Moreover, by using Strong, you improve performance, so make sure you choose it by default:


2 Answers

A rule of thumb

When a parent has a reference to a child object, you should use a strong reference. When a child has a reference to its parent object, you should use a weak reference or a unsafe_unretained one (if the former is not available). A typical scenario is when you deal with delegates. For example, a UITableViewDelegate doesn't retain a controller class that contains a table view.

enter image description here

Here a simple schema to present the main concepts.

Suppose first A,B and C are strong references. In particular, C has a strong ref to its parent. When obj1 is released (somewhere), the A reference doesn't exist anymore but you have a leak since there is a cycle between obj1 and obj2. Speaking in terms of retain counts (only for explain purposes), obj1 has a retain count of 2 (obj2 has a strong reference to it), while obj2 has a retain count of 1. If obj1 is released, its retain count is now 1 and its dealloc method is not called. obj1 and obj2 still remain in memory but no one has a reference to them: Leak.

On the contary, if only A and B are strong refs and C is qualified as weak all is ok. You have no leaks. In fact, when obj1 is released, it also releases obj2. Speaking in terms of retain counts, obj1 has a retain count of 1, obj2 has a retain count of 1. If obj1 is released, its retain count is now 0 and its dealloc method is called. obj1 and obj2 are removed from memory.

A simple suggestion: Start to think in terms of object graph when you deal with ARC.

About your first question, both solutions are valid when you deal with XIBs. In general weak references are used when you deal with memory cycles. Concerning XIBs files, if you use strong you need to set nil in viewDidUnload since if you don't do it, in memory low conditions, you could cause unexpected leaks. You don't release them in dealloc because ARC will do it for you. weak instead doesn't need that treatment since, when the target object is destroyed, those values are set as nil automatically. No dangling pointers anymore.

If you are interested in, I really suggest you to read friday-qa-2012-04-13-nib-memory-management by Mike Ash.

About your second question, if you need to support iOS 4, instead of weak you have to use unsafe_unretained.

Within SO there are a lot of questions/answers. Here the main ones:

How do I replace weak references when using ARC and targeting iOS 4.0?

What kind of leaks does automatic reference counting in Objective-C not prevent or minimize?

using ARC, lifetime qualifier assign and unsafe_unretained

strong / weak / retain / unsafe_unretained / assign

Hope that helps.

Update

As per shaunlim's comment, starting from iOS 6 viewDidUnload method is deprecated. Here I really suggest to see Rob's answer: iOS 6 - viewDidUnload migrate to didReceiveMemoryWarning?.

like image 118
Lorenzo B Avatar answered Oct 03 '22 00:10

Lorenzo B


You can use weak for objects which are connected via IBOutlets to objects in IB because in this case the objects will be there as long as the superview is there. This is because the superview has a strong pointer to its subviews.

If the pointer you are defining is the only pointer to an object you should declare it as strong.

If you are a registered developer I strongly recommend that you have a look into the videos from the WWDC11 and WWDC12. Another good resource is the iOS development podcast from Stanford.

like image 42
dasdom Avatar answered Oct 03 '22 02:10

dasdom