I am interested in retaining cycles.
Let assume we have two views, A and his subview B.
I know that if B has a (custom) delegate defined as
class B: UIView {
var delegate : CustomDelegate?
}
and I set inside A :
b.delegate = self
This create retain cycle, because B has strong reference to A and A has strong reference to be, so neither could be freed.
Question :
What if I have object inside A and I want to pass it to the B object.
class B: UIView {
var object : SomeObject?
}
and inside A :
b.object = self.object
Is this a retaining cycles too? I can't figure this out.
When object (in A) is created it's reference is 1. When it is passed to the B it's reference is 2. But when A try to deallocate itself : When deallocate object in A it reduce reference to 1 and when he try to deallocate B the object reference should go to 0. Is this mean that there is no retaining cycles? Or did B holds indirect reference to A trough object?
Second question :
What could I lose if all object inside B would be weak references? Or better witch object need to be weak?
I assume your first (and only real) question is intended to imply something like this:
class A : UIView {
var object : NSObject
}
class B : UIView {
var object : NSObject
}
... and then we posit that we have an A and a B where the B is a subview of A. So then the A might say:
(self.subviews[0] as! B).object = self.object // or similar
... and you want to know whether there's a retain cycle involved here. No, not in the general case. There are two objects, an A and a B, and they each have a strong reference to the same third object, i.e. something that is neither this A nor this B. There's nothing wrong with that, and indeed it could be crucial that the A and the B both retain the third object. We might question the legitimacy of A telling B what its object should be, and we might legitimately be disturbed by the possibility that the A could mutate this third object behind the B's back (or vice versa); but from a memory management point of view, nothing of interest has happened.
What could I lose if all object inside B would be weak references
You could lose everything. Remember, normal (strong) references are a way of keeping the referenced object alive (retain); that is what memory management of properties is all about. Assigning to a weak reference, on the other hand, doesn't do that, and thus can cause the assigned object to disappear immediately, if nothing else is retaining it. Weak references are only for cases where the lifetime of the referenced object is correctly and entirely determined elsewhere (as in, a superview determines the lifetime of its subviews).
Related
I have been using protocol and delegate method to pass data back to the previous VC after dismissViewControll is called. Below is how I would normally do it as it is not way that most tutorial was written
protocol someVCDelegate {
func somefunction()
}
var delegate: someVCDelegate!
However, I came across this class/weak approach of writing it.
protocol someVCDelegate : class {
func somefunction()
}
weak var delegate: someVCDelegate!
I understand that weak is associated to ARC and avoiding retain cycle. However, I am not sure when I would need it as in all my cases, not doing weak delegate works find (VC does deinit). In what sort of situation would I need weak delegate? Also, why is it "!" after weak, normally it is "?" after weak right?
You say:
However, I am not sure when I would need it as in all my cases, not doing weak delegate works
You only need the weak protocol-delegate pattern when you have a potential for a strong reference cycle, i.e. a circular series of strong references. For example, consider:
an object (the "parent") that has a property (the "child"), i.e. the parent has a strong reference to the child;
the child has a delegate property; and
you set the child's delegate to refer to the parent object.
In that case, it's critical that the delegate be weak reference or else you'll have a strong reference cycle.
Note, this is a trivial example and sometimes the chain of strong references can be rather complicated. For example, consider a UIView subclass that has a delegate property. The potential strong reference cycle can be quite long, from the view controller to its root view, through a series of subviews of subviews, all the way down to the UIView with the delegate that might potentially reference back to the view controller. That will result in a strong reference cycle, too, and we'd be inclined to use a weak reference for that delegate for that reason.
But when you employ protocol-delegate pattern for passing data between view controllers, though, this generally isn't a problem (with the exception of view controller containment) because the presenting view controller doesn't own the presented view controller. The view controller hierarchy generally maintains the strong references to the view controllers. So, when you dismiss the presented view controller, it is deallocated and the potential strong reference cycle is resolved.
Often, we'll instinctually employ the weak protocol-delegate pattern (simply because it prevents strong reference cycles from occurring at all). But sometimes you will use strong references. The most common strong reference pattern is NSURLSession whose delegate is a strong reference. As the documentation for init(configuration:delegate:delegateQueue:) warns us:
The session object keeps a strong reference to the delegate until your app exits or explicitly invalidates the session. If you do not invalidate the session by calling the invalidateAndCancel() or finishTasksAndInvalidate() method, your app leaks memory until it exits.
While this might seem paradoxical, the advantage of this strong reference pattern is that the session knows that it can safely call its delegate methods without fear of the object having been deallocated. (As an aside, this strong delegate behavior of NSURLSession rarely rears its ugly head, because we often use the completion handler methods and don't employ the delegate methods at all, and when we do employ delegate methods, we often have some object other than a view controller as the delegate for the session.)
In short, you really have to evaluate each situation and determine whether the weak reference that we instinctually lean towards is better, or whether you have one of those cases where your protocol is better served with strong references.
Why it's weak: A weak reference is a reference that does not keep a strong hold on the instance it refers to, and so does not stop ARC from disposing of the referenced instance. This behavior prevents the reference from becoming part of a strong reference cycle. Or simply, You resolve strong reference cycles by defining some of the relationships between classes as weak or unowned references instead of as strong references.
And it's "!" after weak because it's implicitly unwrapped. It's gonna have a value.
Sometimes it is clear from a program’s structure that an optional will always have a value, after that value is first set. In these cases, it is useful to remove the need to check and unwrap the optional’s value every time it is accessed, because it can be safely assumed to have a value all of the time.
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.
I can't understand why it is correct to define a delegate with weak pointer :
#property (nonatomic,weak) id delegate;
I can't realize why isn't necessary to retain a reference to the delegate... i don't want the object that i use as the delegate to be deallocated... thus, i would prefer using a strong reference not a weak!
In many cases the delegate is the same object where the instance of my class will be created, in this case creating a weak reference would be a great solution to avoid retain cycle... but what if I choose a totally different object as the delegate ?
I searched for other questions on stack overflow but I can't find something that can help me to fully understand this situation.
The reason that objects weakly retain their delegates is to avoid retain cycles. Imagine the following scenario: object a creates b and retains it, then sets itself as b's delegate. a is released by its owner, leaving a retain cycle containing a and b. This is actually a very common scenario. Consider a view controller that owns a view and acts as that view's delegate. In this case, the view should not retain the controller—as a mater of proper MVC architecture and to prevent retain cycles.
Though retain cycles are a valid concern, the reasoning for a weak reference is more related to apple's perspective on how to use the delegation pattern with uikit and other elements out of the box which is explained here:
http://developer.apple.com/library/IOs/documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html
Specifically:
"The main value of delegation is that it allows you to easily customize the behavior of several objects in one central object."
If the delegate deals with managing the delegated tasks of several objects then those objects need not retain the delegate and should not bear the responsibility of dealllocating the delegate as it might be used by other objects. The weak reference enforces the concept that the management of the delegate is not the delegators responsibility.
An example in objective c is a one delegate being used for multiple table views, like when using a table view and a searchdisplaycontroller with a uisearchbar. Apples examples use the controller as the delegate, but reasoning still holds when using one custom delegate for both the main table view and the results table view for your search. That custom delegate would likely be retained by your controller in order to be provided to both table views.
This is fundamentally different from the basic delegation pattern that is referred to in other languages where the delegate is often created by the delegator and each instance may manage a its own delegate instance.
This is to avoid retain cycles. Apple offers an informative guide on advanced memory management explaining the situation and how best to deal with it. In ARC, they are now known as strong reference cycles, which are explained in the Transitioning to ARC Release Notes.
Previously you would define a property for a delegate like this,
#property (nonatomic, assign) id delegate;
But in ARC, you can define it thus,
#property (nonatomic, unsafe_unretained) id delegate;
Or, for example, if you have a protocol named <MyObjectDelegate>, you can also define the delegate in this way,
#property (nonatomic, weak) id <MyObjectDelegate> delegate;
In other words, in ARC if you have a protocol, you can declare a delegate weak. Otherwise, unsafe_unretained.
As a common practice, if we have two objects holding references with each other, we make the "child" object in a "parent-children" relationship a weak reference.
For delegation patters in iOS, the delegated object is the parent, because there is no need for the delegate caller to exist without the delegated object. For example, you have a sentence object with delegate object for method sentenceShouldEnd. Your paragraph object is the delegated object for your sentence object. Obviously the paragraph object is actually the parent, and in your sentence object you should keep your delegate as a weak reference.
To your point you assign the delegate to self, your understanding is wrong. We should never assign delegate to itself. Why you buy your ticket yourself if you feel it is necessary to hire an agent to buy the ticket for you? You are saying two completely different concepts. When you define a delegate object as property, it's used a weak reference in the object it is defined in(lets say A, i.e. the delegate object is a property of A). The delegate is assigned when you init A(let's say in B), then most likely you would assign A.delegate to self, which is acturally B. You see the parent-child relationship here?? You alloc memory for A in B. You hold A in B. A does not exist without B. You are not assigning the delegate to A!!!!
I am creating an outletCollection of the buttons(present inside my view) in my controller. Since view already has a strong reference to the buttons it contains. On creating this collection Xcode added this code
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
Note the strong keyword in above.
My questions are :
a) Why this code will break if use weak instead of strong ?
b) Do the ownership of array will give me the ownership of objects it contains ?
My thoughts on this :
An array is just a collection of pointers(in this case). Since the parts of heap pointed by those pointers are already owned by view, That's it I can't follow any further :)
It is the array that is being defined with a strong reference. If you make cardButtons weak, then there won't be any other reference to the array and the array will get deallocated.
The buttons will still exist since their parent view still has a reference to them.
Since you need something to keep a reference to the array, its property is defined as strong.
Whether the array is strong, weak, or assign has no effect on the buttons.
The UIButtons are singularly retained by the view, but the NSArray is not. So if you don't retain the NSArray, you can surely access the buttons when you want (for example as subviews of the view), but you can't access them via the array.
And yes, the array by default gives you ownership on the elements.
A) The reference to the collection array must be strong because the view does not reference the array itself. Only the class you are attaching the collection to has a reference to it so it must be a strong reference. If it were weak, the elements of the array would still be in memory, but the array itself would get deallocated.
B) An NSArray always has ownership over the contents of its array unless you use -[NSValue valueWithNonretainedObject:]
a) Why this code will break if use weak instead of strong
Because in case of collection, IB create instance of NSArray and place all references in it. You want to keep that instance of the array (note, not to objects in it, there are already strong references to them exist), because there's no more references to it. If you don't own the array - no one own and it will be released instantly. You can try to replace NSArray with NSPointerArray - it does not have strong references to objects within, for example.
So yes, it will break your code.
b) Do the ownership of array will give me the ownership of objects it
contains ?
Yes, there's already exist collections that does not keep references, I think it just old template and in near future Apple will use them. (NSPointerArray and NSMapTable for example), because current best practice is to have strong reference to top-most view (self.view) and weak to any of its subviews
First of, I am using ARC and targeting iOS4+
I have a custom class that needs a reference to a custom UIViewController.
Unless I have missunderstod something, having the property retain on that reference means that whenever my class destructs, the UIViewController destructs aswell?
Or does it mean that both the appdelegate (which created the UIViewController) and my custom class needs to be deallocated in order for the UIViewController to be deallocated?
So I also read about __unsafe_unretained property. Can my custom class simply use that without complications to reference the UIViewController? Since the appdelegate would deallocate the UIViewController in the end anyway, there is no risk of a dangling pointer?
Thanks
EDIT: The custom class is a singleton object that will live through the entire process if it matters
Each object has a retain count that essentially determines whether or not it needs to stick around. In this case your AppDelegate has retained the UIViewController already (retain count of 1), but that does not mean that your custom class cannot also retain the UIViewController (retain count of 2). So your second scenario is closer to the truth: when your custom class destructs and releases the UIViewController the retain count will drop back to 1. Then, when the AppDelegate destructs and releases it the count will drop to 0 and the object will be destroyed.
To take this a step further, if inside of your custom class you assigned the UIViewController to another bult-in or custom class which also retained it the count would keep going up and then it would drop back as each of those objects in turn released its interest.