Is it wrong for a delegate to have a reference to the object for which it is a delegate?
I am using the delegate pattern for one of my objects. My idea is that I can change the delegate later for another delegate implementing a different strategy. I suppose this is a strategy pattern as a delegate pattern.
My question is, is it really wrong for my delegate to use a reference to the object for which it is a delegate? There are a couple of properties on this object that I need to access no matter which delegate / strategy I am using. If this is bad shape, how do I access the properties?
source to share
I would say yes, this is bad practice. The idea behind a delegate is that it is actually a stand-alone object that receives messages about the object for which it is a delegate ("delegating"). The delegate must have a reference to the delegate and not vice versa, otherwise this is not a true attitude towards delegations.
The preferred way to accomplish what you are asking is to provide a sending object along with any message your delegate receives. For example, you have your delegate instead of a property delegator
, and then, for example, using a method, didDoSomething:(id)anObject
you can remove the property delegator
and send a message delegator:(id)anObject didDoSomething:(id)anotherObject
. This way, you keep the delegate different from the delegate, but access the delegation properties when needed.
This also has the advantage of not providing access to the delegator in methods when you don't really need it; for example, your delegate might have a method didDoSomething
that takes no arguments, not even a delegation, and is just used for logging, as well as a method delegator:(id)anObject didSomethingElse:(id)anotherObject
that calls some properties on the delegator and is much more involved.
Finally, this method allows you to use the same delegate for multiple delegates, since you don't need to update the property delegator
for every delegate object.
For a good example of how this works, have a look at the NSURLConnection documentation, in particular its delegation methods - many of them take the form connection:didDoSomething:
where the first argument is the connection invoking the delegate. Developers typically define a single connection delegate for multiple connections, implementing their delegation methods to perform different actions depending on the properties of the NSURLConnection object being passed.
source to share
This is not bad practice at all. The delegation pattern allows a class to have a common way to talk to any number of objects as long as it implements the same protocol. But the class on which you set the delegate also usually has a number of public properties or methods that allow you to query or change what the class does, in response to which the class can in turn initiate a series of calls to the delegates. So you need the reference of the class you are the delegate to to tell the object is doing something different than it already is, and of course to release it when you're done with it!
This is why it is important to always have any of the properties of the delegate as a destination and not store properties. This way, when the released class is released, it will actually be deallocated, instead of delegating the objects it is holding to invoke a save loop that supports both.
Also why whenever you free yourself you have to set the delegate reference to zero in everything you can have with the delegate reference set. This way the class will not have an invalid delegate reference if the delegate is released before the class that uses the delegate.
source to share