How does UIView prevent retain cycle? - objective-c

Subview has a reference to superview, while superview also has reference (subviews) to subview.
I'm wondering why this doesn't cause retain cycle?

UIView's superview property is declared as
#property(nonatomic, readonly) UIView *superview;
In Objective-C, properties declared without a different ownership specifier are assign by default strong by default as of the introduction of ARC, however, the UIKit headers appear to not be using ARC, so this property is most like assign. Note also, since the property is readonly, there is most likely a custom getter in the source, so the ownership specifier in the property doesn't necessarily tell us anything. It's safe to assume that Apple has implemented it in such a way as to avoid retain cycles.
assign is equivalent to __unsafe_unretained, which is a non-zeroing weak reference. This means that it does not retain the object, but will not be set to nil when the object is deallocated. This has higher performance than weak (since it doesn't need to be checked and zeroed), but unsafe, since you could be accessing garbage memory if the referenced object is deallocated.
Also note, the property is declared as readonly, which means it could actually be implemented as a method that returns a private instance variable, or does something else entirely that we don't know about. Basically, all that matters is that you can assume that this property does not retain the object it refers to.
In new code today, you should be using weak instead of assign.

Related

I want to know the difference between strong, retain, and weak [duplicate]

What are the differences between strong and weak in #property declarations of pointers to objects?
Also, what does nonatomic mean?
It may be helpful to think about strong and weak references in terms of balloons.
A balloon will not fly away as long as at least one person is holding on to a string attached to it. The number of people holding strings is the retain count. When no one is holding on to a string, the ballon will fly away (dealloc). Many people can have strings to that same balloon. You can get/set properties and call methods on the referenced object with both strong and weak references.
A strong reference is like holding on to a string to that balloon. As long as you are holding on to a string attached to the balloon, it will not fly away.
A weak reference is like looking at the balloon. You can see it, access it's properties, call it's methods, but you have no string to that balloon. If everyone holding onto the string lets go, the balloon flies away, and you cannot access it anymore.
A strong reference (which you will use in most cases) means that you want to "own" the object you are referencing with this property/variable. The compiler will take care that any object that you assign to this property will not be destroyed as long as you point to it with a strong reference. Only once you set the property to nil will the object get destroyed (unless one or more other objects also hold a strong reference to it).
In contrast, with a weak reference you signify that you don't want to have control over the object's lifetime. The object you are referencing weakly only lives on because at least one other object holds a strong reference to it. Once that is no longer the case, the object gets destroyed and your weak property will automatically get set to nil. The most frequent use cases of weak references in iOS are:
delegate properties, which are often referenced weakly to avoid retain cycles, and
subviews/controls of a view controller's main view because those views are already strongly held by the main view.
atomic vs. nonatomic refers to the thread safety of the getter and setter methods that the compiler synthesizes for the property. atomic (the default) tells the compiler to make the accessor methods thread-safe (by adding a lock before an ivar is accessed) and nonatomic does the opposite. The advantage of nonatomic is slightly higher performance. On iOS, Apple uses nonatomic for almost all their properties so the general advice is for you to do the same.
strong: assigns the incoming value to it, it will retain the incoming value and release the existing value of the instance variable
weak: will assign the incoming value to it without retaining it.
So the basic difference is the retaining of the new variable.
Generaly you want to retain it but there are situations where you don't want to have it otherwise you will get a retain cycle and can not free the memory the objects. Eg. obj1 retains obj2 and obj2 retains obj1. To solve this kind of situation you use weak references.
A dummy answer :-
I think explanation is given in above answer, so i am just gonna tell you where to use STRONG and where to use WEAK :
Use of Weak :-
1. Delegates
2. Outlets
3. Subviews
4. Controls, etc.
Use of Strong :-
Remaining everywhere which is not included in WEAK.
strong and weak, these keywords revolves around Object Ownership in Objective-C
What is object ownership ?
Pointer variables imply ownership of the objects that they point to.
When a method (or function) has a local variable that points to an object, that variable is said to own the object being pointed to.
When an object has an instance variable that points to another object, the object with the pointer is said to own the object being pointed to.
Anytime a pointer variable points to an object, that object has an owner and will stay alive. This is known as a strong reference.
A variable can optionally not take ownership of an object that it points to. A variable that does not take ownership of an object is known as a weak reference.
Have a look for a detailed explanation here Demystifying #property and attributes
Here, Apple Documentation has explained the difference between weak and strong property using various examples :
https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW3
Here, In this blog author has collected all the properties in same place. It will help to compare properties characteristics :
http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html
strong is the default. An object remains “alive” as long as there is a strong pointer to it.
weak specifies a reference that does not keep the referenced object alive. A weak reference is set to nil when there are no strong references to the object.
To understand Strong and Weak reference consider below example, suppose we have method named as displayLocalVariable.
-(void)displayLocalVariable
{
UIView* myView = [[UIView alloc] init];
NSLog(#"myView tag is = %ld", myView.tag);
}
In above method scope of myView variable is limited to displayLocalVariable method, once the method gets finished myView variable which is holding the UIView object will get deallocated from the memory.
Now what if we want to hold the myView variable throughout our view controller's life cycle. For this we can create the property named as usernameView which will have Strong reference to the variable myView(see #property(nonatomic,strong) UIView* usernameView; and self.usernameView = myView; in below code), as below,
#interface LoginViewController ()
#property(nonatomic,strong) UIView* usernameView;
#property(nonatomic,weak) UIView* dummyNameView;
- (void)displayLocalVariable;
#end
#implementation LoginViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void)viewWillAppear:(BOOL)animated
{
[self displayLocalVariable];
}
- (void)displayLocalVariable
{
UIView* myView = [[UIView alloc] init];
NSLog(#"myView tag is = %ld", myView.tag);
self.usernameView = myView;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
Now in above code you can see myView has been assigned to self.usernameView and self.usernameView is having a strong reference(as we declared in interface using #property) to myView. Hence myView will not get deallocated from memory till self.usernameView is alive.
Weak reference
Now consider assigning myName to dummyNameView which is a Weak reference, self.dummyNameView = myView; Unlike Strong reference Weak will hold the myView only till there is Strong reference to myView. See below code to understand Weak reference,
-(void)displayLocalVariable
{
UIView* myView = [[UIView alloc] init];
NSLog(#"myView tag is = %ld", myView.tag);
self.dummyNameView = myView;
}
In above code there is Weak reference to myView(i.e. self.dummyNameView is having Weak reference to myView) but there is no Strong reference to myView, hence self.dummyNameView will not be able to hold the myView value.
Now again consider the below code,
-(void)displayLocalVariable
{
UIView* myView = [[UIView alloc] init];
NSLog(#"myView tag is = %ld", myView.tag);
self.usernameView = myView;
self.dummyNameView = myView;
}
In above code self.usernameView has a Strong reference to myView, hence self.dummyNameView will now have a value of myView even after method ends since myView has a Strong reference associated with it.
Now whenever we make a Strong reference to a variable it's retain count get increased by one and the variable will not get deallocated till it's retain count reaches to 0.
Hope this helps.
Strong: Basically Used With Properties we used to get or send data from/into another classes.
Weak: Usually all outlets, connections are of Weak type from Interface.
Atomic: Such type of properties are used in conditions when we don't want to share our outlet or object into different simultaneous Threads. In other words, Atomic instance make our properties to deal with one thread at a time.
Hopefully it helpful for you.

Want to perform action when __weak ivar is niled

I have a #class Foo which contains a __weak id bar ivar. Several actions from methods in different classes can cause the object to disappear and thus get bar niled.
I want to perform an action when the ivar is automatically niled by ARC.
If possible, I would want to avoid turning bar into a property or using Key-Value Observing.
Is this even possible? If not, can KVO be used against non-property ivars?
I was led here by a duplicate question, here is what I answered:
You can't do that with KVO, but you can still get a notification and emulate this by associating an object with your iVar using objc_setAssociatedObject(), it will be deallocated when the weak variable dies.
#interface WeakObjectDeathNotifier : NSObject
#end
#implementation WeakObjectDeathNotifier
- (void)dealloc
{
// the code that shall fire when the property will be set to nil
}
#end
You can build on top of that very elaborate notifiers, using NSNotificationCenter or just custom blocks, depending on how heavily you rely on that for a specific ivar case or for lots of them.
The good thing about this solution is that it works with any __weak ivar, even if you don't control the type the __weak ivar has.
KVO cannot be successfully used on non-property IVARs.
You cannot detect from the runtime when Objective-C's ARC nils an IVAR.
I suggest to override dealloc. If you know the type of the object that will be allocated, and it's a custom class (otherwise subclass it), you can perform the action when the object is deallocated, which is exactly what happens when ARC sets the retain count to zero and sets the weak variable to nil.

Is retain attribute for UIView properties with ARC required?

Before ARC, you would declare properties in your .h file as:
#property (nonatomic,retain) UIView *someUIView;
With ARC, do I still need to use retain or can I just write this?
#property (nonatomic) UIView *someUIView;
In LLVM 3.1 and later, you can do either, because they're the same. Under ARC, strong (which is the same as retain) is the default, if not specified, for retainable object pointers.
Quoting from the LLVM ARC doc:
A property of retainable object pointer type which is synthesized
without a source of ownership has the ownership of its associated
instance variable, if it already exists; otherwise, [beginning Apple
3.1, LLVM 3.1] its ownership is implicitly strong. Prior to this revision, it was ill-formed to synthesize such a property.
I usually find myself typing "strong" anyway, I think because since assign was previously the default, it scares me for just a split second every time I see a retainable object property with no ownership specified.
The strong keyword has been advertised on place of retain, but they are really the same thing. So you can use strong or retain.
Your view WILL need to be retained by at least one object. If your view is already being retained by another object, you could make it an assign (aka weak) property. Otherwise you could keep the retain or strong keyword.

Differences between strong and weak in Objective-C

What are the differences between strong and weak in #property declarations of pointers to objects?
Also, what does nonatomic mean?
It may be helpful to think about strong and weak references in terms of balloons.
A balloon will not fly away as long as at least one person is holding on to a string attached to it. The number of people holding strings is the retain count. When no one is holding on to a string, the ballon will fly away (dealloc). Many people can have strings to that same balloon. You can get/set properties and call methods on the referenced object with both strong and weak references.
A strong reference is like holding on to a string to that balloon. As long as you are holding on to a string attached to the balloon, it will not fly away.
A weak reference is like looking at the balloon. You can see it, access it's properties, call it's methods, but you have no string to that balloon. If everyone holding onto the string lets go, the balloon flies away, and you cannot access it anymore.
A strong reference (which you will use in most cases) means that you want to "own" the object you are referencing with this property/variable. The compiler will take care that any object that you assign to this property will not be destroyed as long as you point to it with a strong reference. Only once you set the property to nil will the object get destroyed (unless one or more other objects also hold a strong reference to it).
In contrast, with a weak reference you signify that you don't want to have control over the object's lifetime. The object you are referencing weakly only lives on because at least one other object holds a strong reference to it. Once that is no longer the case, the object gets destroyed and your weak property will automatically get set to nil. The most frequent use cases of weak references in iOS are:
delegate properties, which are often referenced weakly to avoid retain cycles, and
subviews/controls of a view controller's main view because those views are already strongly held by the main view.
atomic vs. nonatomic refers to the thread safety of the getter and setter methods that the compiler synthesizes for the property. atomic (the default) tells the compiler to make the accessor methods thread-safe (by adding a lock before an ivar is accessed) and nonatomic does the opposite. The advantage of nonatomic is slightly higher performance. On iOS, Apple uses nonatomic for almost all their properties so the general advice is for you to do the same.
strong: assigns the incoming value to it, it will retain the incoming value and release the existing value of the instance variable
weak: will assign the incoming value to it without retaining it.
So the basic difference is the retaining of the new variable.
Generaly you want to retain it but there are situations where you don't want to have it otherwise you will get a retain cycle and can not free the memory the objects. Eg. obj1 retains obj2 and obj2 retains obj1. To solve this kind of situation you use weak references.
A dummy answer :-
I think explanation is given in above answer, so i am just gonna tell you where to use STRONG and where to use WEAK :
Use of Weak :-
1. Delegates
2. Outlets
3. Subviews
4. Controls, etc.
Use of Strong :-
Remaining everywhere which is not included in WEAK.
strong and weak, these keywords revolves around Object Ownership in Objective-C
What is object ownership ?
Pointer variables imply ownership of the objects that they point to.
When a method (or function) has a local variable that points to an object, that variable is said to own the object being pointed to.
When an object has an instance variable that points to another object, the object with the pointer is said to own the object being pointed to.
Anytime a pointer variable points to an object, that object has an owner and will stay alive. This is known as a strong reference.
A variable can optionally not take ownership of an object that it points to. A variable that does not take ownership of an object is known as a weak reference.
Have a look for a detailed explanation here Demystifying #property and attributes
Here, Apple Documentation has explained the difference between weak and strong property using various examples :
https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW3
Here, In this blog author has collected all the properties in same place. It will help to compare properties characteristics :
http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html
strong is the default. An object remains “alive” as long as there is a strong pointer to it.
weak specifies a reference that does not keep the referenced object alive. A weak reference is set to nil when there are no strong references to the object.
To understand Strong and Weak reference consider below example, suppose we have method named as displayLocalVariable.
-(void)displayLocalVariable
{
UIView* myView = [[UIView alloc] init];
NSLog(#"myView tag is = %ld", myView.tag);
}
In above method scope of myView variable is limited to displayLocalVariable method, once the method gets finished myView variable which is holding the UIView object will get deallocated from the memory.
Now what if we want to hold the myView variable throughout our view controller's life cycle. For this we can create the property named as usernameView which will have Strong reference to the variable myView(see #property(nonatomic,strong) UIView* usernameView; and self.usernameView = myView; in below code), as below,
#interface LoginViewController ()
#property(nonatomic,strong) UIView* usernameView;
#property(nonatomic,weak) UIView* dummyNameView;
- (void)displayLocalVariable;
#end
#implementation LoginViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void)viewWillAppear:(BOOL)animated
{
[self displayLocalVariable];
}
- (void)displayLocalVariable
{
UIView* myView = [[UIView alloc] init];
NSLog(#"myView tag is = %ld", myView.tag);
self.usernameView = myView;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
Now in above code you can see myView has been assigned to self.usernameView and self.usernameView is having a strong reference(as we declared in interface using #property) to myView. Hence myView will not get deallocated from memory till self.usernameView is alive.
Weak reference
Now consider assigning myName to dummyNameView which is a Weak reference, self.dummyNameView = myView; Unlike Strong reference Weak will hold the myView only till there is Strong reference to myView. See below code to understand Weak reference,
-(void)displayLocalVariable
{
UIView* myView = [[UIView alloc] init];
NSLog(#"myView tag is = %ld", myView.tag);
self.dummyNameView = myView;
}
In above code there is Weak reference to myView(i.e. self.dummyNameView is having Weak reference to myView) but there is no Strong reference to myView, hence self.dummyNameView will not be able to hold the myView value.
Now again consider the below code,
-(void)displayLocalVariable
{
UIView* myView = [[UIView alloc] init];
NSLog(#"myView tag is = %ld", myView.tag);
self.usernameView = myView;
self.dummyNameView = myView;
}
In above code self.usernameView has a Strong reference to myView, hence self.dummyNameView will now have a value of myView even after method ends since myView has a Strong reference associated with it.
Now whenever we make a Strong reference to a variable it's retain count get increased by one and the variable will not get deallocated till it's retain count reaches to 0.
Hope this helps.
Strong: Basically Used With Properties we used to get or send data from/into another classes.
Weak: Usually all outlets, connections are of Weak type from Interface.
Atomic: Such type of properties are used in conditions when we don't want to share our outlet or object into different simultaneous Threads. In other words, Atomic instance make our properties to deal with one thread at a time.
Hopefully it helpful for you.

Keeping pointers to subviews

Subviews added to a view are automatically retained by the view. Suppose you want to have a separate pointer to the same subview so you don't need to constantly retrieve it via its tag.
What type of #property is necessary for such a case? I assume that setting the property to retain is not a good idea since the main view is already retaining it? Should it be assign?
Or, is using #property entirely unnecessary here unless you plan to re-assign it later or refer to it with dot notation?
You can use either retain or assign.
Of course, if you use retain, you have to set the property to nil or release its object in viewDidUnload and dealloc.
The reason some people prefer retain is because it means the property is still valid in viewDidUnload. So if you have other cleanup to do, and that cleanup requires the view to still exist, you can do it in viewDidUnload.
If you use assign, you don't have to set the property to nil in viewDidUnload and dealloc (though it would be good practice). However, by the time you receive viewDidUnload, the view has already been released, so you can't use it at that point for other cleanup. Instead you have to override didReceiveMemoryWarning to do the cleanup before calling [super didReceiveMemoryWarning].
In iOS 5.0, you can do the cleanup in viewWillUnload instead of overriding didReceiveMemoryWarning.
Consider these two things:
There's no problem with retaining an object several times provided that each retain is balanced with release. With respect to properties, this just means that you should set your property to nil when you're done with it.
The basic idea behind memory management in Objective-C is that you worry about retaining the objects that you're using and let other objects worry about the objects that they're using.
Considering these, I'd advocate using retain. If you rely on he fact that a view retains its subviews, you've suddenly made your code dependant on external behavior. I'm not saying that UIView is likely to stop retaining its subviews, but if you keep a non-retained reference to a subview and later remove that subview from its superview you're code is likely to crash.
Some folks do use assign for outlets pointing to subviews when they know those subviews will never be removed. Personally, I don't see the point of relying on another object to retain something for you when retaining that thing yourself is so simple and cheap.