Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are Objective-C delegates usually given the property assign instead of retain?

People also ask

Why delegate is never retained?

The rule is to not retain it because it's already retained elsewhere and more important you'll avoid retain cycles.

What does delegate mean in Objective-C?

A delegate is an object that acts on behalf of, or in coordination with, another object when that object encounters an event in a program. The delegating object is often a responder object—that is, an object inheriting from NSResponder in AppKit or UIResponder in UIKit—that is responding to a user event.

Is delegate retained?

The delegate object is retained by the receiver. This is a rare exception to the memory management rules described in Advanced Memory Management Programming Guide. An instance of CAAnimation should not be set as a delegate of itself.

What are Objective-C properties?

The Objective-C declared properties feature provides a simple way to declare and implement an object's accessor methods.


The reason that you avoid retaining delegates is that you need to avoid a retain cycle:

A creates B A sets itself as B's delegate … A is released by its owner

If B had retained A, A wouldn't be released, as B owns A, thus A's dealloc would never get called, causing both A and B to leak.

You shouldn't worry about A going away because it owns B and thus gets rid of it in dealloc.


Because the object sending the delegate messages does not own the delegate.

Many times, it's the other way around, as when a controller sets itself as the delegate of a view or window: the controller owns the view/window, so if the view/window owned its delegate, both objects would be owning each other. This, of course, is a retain cycle, similar to a leak with the same consequence (objects that should be dead remain alive).

Other times, the objects are peers: neither one owns the other, probably because they are both owned by the same third object.

Either way, the object with the delegate should not retain its delegate.

(There's at least one exception, by the way. I don't remember what it was, and I don't think there was a good reason for it.)


Addendum (added 2012-05-19): Under ARC, you should use weak instead of assign. Weak references get set to nil automatically when the object dies, eliminating the possibility that the delegating object will end up sending messages to the dead delegate.

If you're staying away from ARC for some reason, at least change assign properties that point to objects to unsafe_unretained, which make explicit that this is an unretained but non-zeroing reference to an object.

assign remains appropriate for non-object values under both ARC and MRC.


Note that when you have a delegate that's assign, it makes it very important to always set that delegate value to nil whenever the object is going to be deallocated - so an object should always be careful to nil out delegate references in dealloc if it has not done so elsewhere.


One of the reason behind that is to avoid retain cycles. Just to avoid the scenario where A and B both object reference each other and none of them is released from memory.

Acutally assign is best for primitive types like NSInteger and CGFloat, or objects you don't directly own, such as delegates.