Strong and weak modifiers with ios interface elements

I donโ€™t use Interface Builder in my projects, and I noticed one thing that I donโ€™t know how to explain. Yet. So to the point. When we use IB and define user interface elements such as UILabel or UIButton in our controller, we use this ugly IBOutlet prefix and a "weak" modifier. It works like music. But when we decide not to use IB and define the entire user interface from the code, it just doesn't work.

Suppose I want to add a UILabel to a controller (using IB). I will have something like this file I * .h:

@property (nonatomic, weak) IBOutlet UILabel * label; 

And I do not need to do anything in the * .m file. But if I delete the * .xib file and try to configure my UILabel in, for example, one of the init methods, for example:

 self.label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,100,20)]; self.label.text = @"some text"; [self.view addSubview:self.label]; 

This does not work until I redo my * .h file:

 @property (nonatomic, strong) UILabel * label; 

Now, I know the difference between weak and strong, but I have no idea why we can use weak ui elements when using IB? Something must contain strong indications of these elements, right? But what?? In the second case, this is the controller, but I do not understand how it behaves in the first case.

+6
source share
3 answers

Something must contain strong indications of these elements, right? But what??

That's right, you must have at least 1 strong reference to the object in order for it to exist. You will need to have a strong link to the objects of the root level of the user interface, everything below this can be weak (since the parent objects will have their children). A .xib file in coordination with its file owner would do this for you.

See this document on how xib files xib . In particular, this snipp:

You usually need strong references to top-level objects to ensure that they will not be freed; you donโ€™t need strong references to the objects below on the chart, because they belong to their parents, and you should minimize the risk of creating strong reference cycles.

From a practical point of view, in iOS and OS X, outputs should be defined as declared properties. Outlets, as a rule, should be weak, except for those that belong to the file owner, for top-level objects in the nib file (or in iOS, the storyboard scene), which should be strong. Therefore, the blinds you create should be weak.

+2
source

The reason Interface Builder creates weak links for IBOutlets is as follows:

IB knows that a view is retained in its view. Thus, any object in the view tree does not need strong links except the root object. The view controller stores this strong link in its main view property.

Now that the view is unloaded (at least until iOS 5), the UIViewController view property is set to nil, freeing up the main view. If the IBOutlets for the subviews of this supervisor are strong references, they would store part of the hierarchy of views in memory. This is undesirable (and can lead to confusion when accessing these orphan views).

+4
source

Despite the accepted answer, here is how you can do it in code :

 UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,100,20)]; // strong ref label.text = @"some text"; [self.view addSubview:label]; // strong ref from superview self.label = label; // weak ref // Now you can do `label = nil;` 

This is the XIB download point. label already has a supervisor when it is assigned your weak property.

+1
source

All Articles