60

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.

MatterGoal
  • 16,038
  • 19
  • 109
  • 186
  • possible duplicate of [Why are Objective-C delegates usually given the property assign instead of retain?](http://stackoverflow.com/questions/918698/why-are-objective-c-delegates-usually-given-the-property-assign-instead-of-retai) – Barry Wark Dec 09 '11 at 17:09
  • 5
    @BarryWark why ? i'm asking for weak... not assign. Is similar for sure but it's not the same argument. – MatterGoal Dec 09 '11 at 17:11
  • In this case, `weak` is `assign` with the added benefit that the reference is nil'd when the delegate is deallocated. In previous runtimes, the delegate had to remove itself as the delegate before deallocation else it would leave a dangling pointer. The answers to the reference question still answer your question as well. – Barry Wark Dec 09 '11 at 17:13
  • 1
    @BarryWark and the answer you linked me speak about a direct delegation between 2 objects where A creates B and assign itself as delegate of B. I'm ask for a different environment... i.e. A creates B and C is a delegate for B. – MatterGoal Dec 09 '11 at 17:13
  • weak is the ARC equivalent of assign. It gives some extra safety by niling, but that's not the main point. – Eiko Dec 09 '11 at 17:13
  • 3
    New memory management techniques, new best practices, I don't think this is a dupe. – William Denniss Jan 31 '12 at 00:05

4 Answers4

96

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.

Barry Wark
  • 107,306
  • 24
  • 181
  • 206
  • 2
    Thanks, but how it can be relevant in a situation like that : `A` creates `B` and `B` has as delegate `C` – MatterGoal Dec 09 '11 at 17:17
  • @Barry Wark - Just curious, what does the "..., leaving the a<=>b retain cycle..." mean? Also you state in your scenario that a view owns a particular view and acts as the delegate, and that the view should not retain the controller. I'm a little confused by what you mean, care to explain a little bit further? – 5StringRyan Dec 09 '11 at 18:32
  • 5
    @MatterGoal in the case you ask about, it's true that it may not be necessary to weakly hold the delegate. If you know for sure that the third object won't create a retain cycle, sure, go for it. But having that knowledge introduces coupling. You don't usually code to a particular case, but to a generic case, and the best practice to be future proof in this case is to weakly hold the delegate. – Victor Jalencas May 17 '14 at 18:07
27

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.

kocodude
  • 694
  • 1
  • 6
  • 13
  • This is the best answer for me - but would be good to understand the down points of not including - what are the implications ? bugs/ slow experience? – UKDataGeek May 09 '16 at 16:23
18

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.

john
  • 3,043
  • 5
  • 27
  • 48
3

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

Jason
  • 39
  • 1