Edward Dale
Edward Dale

Reputation: 30143

Is it bad practice for a delegate to have a reference to the object for which it is the delegate?

I'm using the delegate pattern for one of my objects. My idea is that I will be able to swap the delegate out later for a different delegate implementing a different strategy. I suppose this is just as much the strategy pattern as the delegate pattern.

My question is, is it bad practice for my delegate to have a reference back to the object for which it is the delegate? There are a couple properties of that object that I need to have access to regardless of which delegate/strategy I use. If this is bad form, how should I get access to the properties?

Upvotes: 2

Views: 1247

Answers (4)

It is not at all bad practice. The delegate pattern allows for a class to have a generic way to talk to any number of objects as long as the implement the same protocol. But the class on which you set the delegate also will usually have a number of public properties or methods that allow you to query or alter what the class is doing, in response to which the class may in turn trigger a number of the delegate calls. So you need a reference of the class to which you are the delegate, in order to tell the object to do something different than it is already, and of course to release it when you are through with it!

This is also why it's important to always have any delegate properties as assign, and not retain, properties. That way when the originating class is released it will actually be released, instead of having delegate objects it is holding onto causing a retain loop that keeps both around.

It's also why whenever you are being released, you should set the delegate reference to nil in anything you may have a delegate reference set. This way a class will not have an invalid delegate reference if the delegate is released before the class that uses a delegate.

Upvotes: 3

Ozan
Ozan

Reputation: 4415

Generally a dependency should not have a reference back to the dependent object, as this would be a classical circle reference. To avoid having a back-reference you can supply the needed properties as arguments in a delegate method, or you move the properties themselves into the delegate.

Upvotes: 2

Tim
Tim

Reputation: 60130

I'd say yes, it's bad practice. The idea behind a delegate is that it's effectively a standalone object that receives messages about the object for which it is the delegate (the "delegator"). The delegator should have a reference to the delegate, not the other way around, otherwise it's not a true delegation relationship anymore.

A preferred way to accomplish what you're asking is to provide the sending object along with whatever message your delegate receives. For example, on your delegate, instead of having a delegator property and then receiving, for example, a didDoSomething:(id)anObject method, you could remove the delegator property and send the message delegator:(id)anObject didDoSomething:(id)anotherObject. This way, you keep the delegate distinct from the delegator, but still get access to the delegator's properties when you need them.

This way also has the advantage of not providing access to the delegator in methods when you don't truly need it; for example, your delegate could have a didDoSomething method that takes no arguments, not even a delegator, and is just used for logging, as well as a delegator:(id)anObject didSomethingElse:(id)anotherObject method that calls some properties on the delegator and is much more involved.

Finally, this method allows you to use the same delegate for multiple delegators, since you don't need to update a delegator property for each delegate object.

For a good example of how this works, take a look at the NSURLConnection documentation, specifically its delegate methods - a lot of them take the form connection:didDoSomething:, where the first argument is the connection calling the delegator. Developers commonly define a single connection delegate for multiple connections, implementing their delegate methods to do different things depending on properties of the NSURLConnection object passed in.

Upvotes: -1

Chuck
Chuck

Reputation: 237070

Not necessarily. For example, it's quite common for a "controller"-type object to create data objects and views and make itself the delegate of some of those objects in order to properly control things.

Upvotes: 9

Related Questions