Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does IBOutlet imply __weak?

Just starting out with ARC. Pre-ARC, I would just simply declare my outlets as for example: IBOutlet UIButton *button; so I am not retaining it or anything. With ARC, not specifying weak or strong implies strong.

So if I do the same thing under ARC (i.e. IBOutlet UIButton *button;), does this mean button is a strong reference? or Do I have to explcility define it as weak?

In short, does IBOutlet imply __weak?

like image 938
0xSina Avatar asked Apr 25 '12 03:04

0xSina


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 is IBOutlet weak in Swift?

Outlets that you create will therefore typically be weak by default, because: Outlets that you create to, for example, subviews of a view controller's view or a window controller's window, are arbitrary references between objects that do not imply ownership.

What is the purpose of an IBOutlet?

An IBOutlet helps connect the object control to the code to make the object accessible via the program. IBOutlet makes the connection between the declared instance variables wit the elements in the prototype cell. It typically holds these other objects as properties backed by instance variables.

What is @IBOutlet weak VAR?

@IBOutlet private weak var someLabel: UILabel? This ensures that if the label is removed from the superview, it's not being kept in memory by the strong reference in the view controller.


3 Answers

The word IBOutlet is actually defined as nothing:

#define IBOutlet

Xcode just uses the presence of this word in your code for purposes of allowing you to make connections in Interface Builder. A declaration of a variable or a property as an IBOutlet:

IBOutlet UIButton * button;
@property (...) IBOutlet UIButton * button;

therefore doesn't have any direct effect as far as ARC is concerned; it doesn't (although, conceivably, it could) translate into __weak or anything like that. The word itself is entirely gone from your source by the time the compiler gets it.

On the other hand, the fact that this variable or property is an outlet does have a meaningful effect on how you need to think about the memory management.

The implicit storage qualifier for an object variable declaration like IBOutlet UIButton * button; under ARC is __strong, as you said -- any object assigned to the variable will be considered "owned". Under MRR, the declaration is just a pointer; assigning to has no effect on the reference count/ownership of the assigned object -- it acts in the same way as an assign property.* So the meaning of the same ivar declaration changes between the two management systems.

Objects in a xib have owned/owner relationships that are formed by the view hierarchy; that is, parent views own their subviews. The top-level view in a xib is owned by the object known as File's Owner. This setup means that, generally speaking, your outlets to objects in an xib that are not top-level should be weak (under ARC) or assign (if a property under MRR). They are not owning relationships; they are essentially convenient indexes into the view list. This is Apple's recommendation:

...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.

[...]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. Outlets that you create should will [sic] therefore typically be weak by default...

Your simple pointer IBOutlets, as I explained, acted -- for memory management purposes -- like weak properties,** which means that they were doing the right thing. The same declaration becomes probably the wrong thing when compiled under ARC.

In summary: IBOutlet does not translate into weak, but it does change the meaning of the pointer. Since the default memory management semantics of IBOutlet UIButton * button; change from "assign" under MRR to "owned" under ARC, and since IBOutlets should generally be non-owning, the presence of IBOutlet does indeed imply that the pointer should be declared __weak under ARC.


*And similar to a weak property -- the only difference there is that weak pointers are set to nil when the object is deallocated.

**Except for the auto-nil part.

Or, really, it should be a weak property.

like image 200
jscs Avatar answered Oct 16 '22 08:10

jscs


No, IBOutlet is basically stripped when the code is compiled. It is however a helper for XCode so that it can know WHAT is an InterfaceBuilderOutlet.

Basically this word will let you connect the element in the Interface Builder.

By default it will still be strong (just imagine that word isn't there).

However it is suggested that you set it to weak because once something is connected to the interface builder, THAT interface will keep a strong reference to it, so there is no point at having a double strong reference, specially if that element is not meant to be kept alive when the interface has been unloaded.

Read this question which is exactly what you are looking for:

Should IBOutlets be strong or weak under ARC?

like image 38
Pochi Avatar answered Oct 16 '22 08:10

Pochi


The IBOutlet keyword is only used to associate the object with an element in Interface Builder. It has nothing to do with weak or strong or ARC or memory management.

like image 3
bbarnhart Avatar answered Oct 16 '22 07:10

bbarnhart