Monday, March 28, 2011

Delegates - To assign or to retain?

Well, the right answer is that delegates need to be marked as assign.

What I mean by assign is when you create a property for the delegate it should be as follows:
@property(nonatomic, assign) id delegate;

Why does it matter?

The whole reason behind this is related to retain cycles. The concept is clearly mentioned in the apple docs (see the section 'Retain cycles' in the Apple docs).

There can be two cases here. However, I feel the second case is the one that occurs more frequently:

Case 1: If a classA has retained the delegate object of classB and classB has retained an instance of classA , then the problem here is that neither classA nor classB will ever be released from memory. Because classB's reference count cannot become zero unless classA is released and the classA object won't be released unless classB is deallocated.

Case 2: If "some class" has retained classA. and ClassB (which is the child of class A) has retained classA via a delegate. In this case, class A will not get released even if "some class" releases it because its retain count will not become zero. Since the parent's retain count has not reached zero, its dealloc is never called so it cannot send a release message to the child.

So if we assign the delegate instead of retaining it, there will be no problem of retain cycles.

Points to Note:
1. In this case, if the delegate is called after the object is already deallocated, your application will crash. So if your class is a delegate of some object which is going to be released, make sure you set that delegate to nil before releasing it.

2. Always call respondsToSelector on a delegate method to ensure it has been implemented before you call it.

No comments:

Post a Comment