If I follow any of a number of examples available on the web, I see a common theme emerge with the delegate pattern:
myClass.delegate = self;
From what I read, delegation is supposed to uncouple behavior, but allow interaction between classes, however, only assigning a single delegate seems to be 100% at odds with this behavior.
I have a web dev background, and I am intimately familiar with pub/sub patterns, but what I'm trying to wrap my head around is why I would only allow a single delegate (self) to be able to act on whatever happens in myClass. That would seem to ruin the entire point of delegation.
Maybe I'm misunderstanding something, or maybe this is only the simplest form of delegation, but could someone please explain how statically assigning (in the classic sense) one class to another's delegate decouples behavior in any meaningful way.
Bonus: Perhaps a way to allow multiple classes to act on a delegation.
The delegate asserts additional control over the delegated class. The most simple example is windowShouldClose: method in the NSWindowDelegate protocol. The class delegate gets a chance to proactively override closing the window in NSWindow. If multiple delegates were allowed, multiple delegates could supply conflicting orders which would be an undesirable result.
Delegation allows you to customize behavior without subclassing. Because a class can implement many delegate protocols, it is a key part of the MVC programming model in Objective-C. Delegation allows you to create one class as a "Controller" of multiple other classes.
For acting reactively to what happens to the class, you use a pub/sub model of key value observing. For example, NSOperationQueue has an observable property operationCount to let you react to changes in the number of operations in the queue.
It decouples behavior in the sense that the delegator needn't know anything at all about the delegate other than that it (possibly) responds to a certain set of methods. This makes it so that classes that have delegate can be used in entirely different codebases/situation without changes. It's particularly applicable when writing Framework classes that will be used by someone else, which is one reason you see it so much in the system frameworks.
One of the major uses of delegation is to allow customization of an object's behavior without subclassing. Take for example the NSWindowDelegate method -windowWillResize:toSize:, where the delegate can return a different size than the suggested one to implement custom sizing behavior. How would this scenario be handled with multiple delegates each returning a different value?
Of course, sometimes delegate methods are merely meant to inform the delegate that some particular event has occurred. In these cases, it is indeed reasonable for multiple objects to want to be notified. This is provided for in Objective-C/Cocoa by notifications (NSNotification), and Key Value Observing (KVO). You'll find plenty of cases in Cocoa where a delegate method also has a corresponding notification posted in case objects other than the delegate want to know about it (e.g. windowWillClose:/NSWindowWillCloseNotification).
Related
I have next issue:
I have a decorator for the NSButtonCell class, which adds some functionality. As it is a decorator - is's a subclass of NSButtonCell. I didn't like to create subclasses, because the same functionality must be dynamically added\removed to some other subclasses of NSButtonCell. And, as it is a decorator, I must forward all messages to the decorated object, because some subclass can have own 'setting', behaviour and etc. Because NSButtonCell has many methods, I can't write code to redirect all messages to decorated object. Please, tell me, how I can redirect all received messages to decorated object?
Round Peg meet Square Hole.
The reason why you are finding it so hard to do this is because it is an exceedingly non-standard pattern to use for implementing UI. Method forwarding as implemented by either forwardInvocation: or NSProxy is useful, but pretty much never used to implement the Decorator pattern in the context of the UI.
While you could use a subclass of NSProxy that selective forwards or implements the methods you need, that is a complete waste of code compared to simply creating a subclass.
Just use a subclass and be done with it.
However, only subclass if you really need to. If the provided NSButtonCell can do all that you need and it is merely a matter of configuring it, then configure it in your controller or in whatever mechanism that you use to layout and present your user interface.
And in your case, it sounds like a central controller or UI configurator is the way to go as that will centralize the functionality into a single spot that can then control multiple (potentially minimal subclasses) instances of the various UI classes.
Using NSProxy is the standard approach for creating objects that act as stand-ins for other objects or objects that don’t exist yet. Its entire structure is based around handling methods and forwarding them to the true object.
This is a pretty general question, but I was wondering today about delegates. At this point I don't really have a specific time I do use them or don't use them - aside from obvious cases, like passing selections from a picker or tableview stuff. For example, if there's a situation where I can pass a reference to an object around and use that to call methods, is there a reason to implement a delegate? In summary, what is the delegate pattern intended for use in and when is it better to NOT use it?
Thanks for the quick and comprehensive answers! They were all extremely helpful.
The advantage of the delegate pattern is loose coupling between the delegating object and its delegate. Loose coupling improves a class's reusability in other contexts.
The delegating object doesn't have to know anything about the object it communicates with (aside from the requirement that it implement the delegate protocol) – especially not its class or what methods it has. If you later want to reuse your component in a different context or have it communicate with another object of a different class, all this object has to do is implement the delegate protocol. The delegating object does not have to be changed at all.
There is also a downside to this, of course, and that is that a bit more code is required and the code you write is not as explicit and therefore may be a bit harder to understand. Whether this (generally small) tradeoff is worth it depends on your use case. If the two objects are tightly coupled anyway and the probability of reuse in the future is low, using the delegate pattern might be overkill.
See this discussion
A delegate allows one object to send messages to another object when an event happens.
Pros
Very strict syntax. All events to be heard are clearly defined in
the delegate protocol.
Compile time Warnings / Errors if a method is not implemented as it should be by a delegate.
Protocol defined within the scope of the controller only.
Very traceable, and easy to identify flow of control within an application.
Ability to have multiple protocols defined one controller, each with different delegates.
No third party object required to maintain / monitor the communication process.
Ability to receive a returned value from a called protocol method. This means that a delegate can help provide information back
to a controller.
Cons
Many lines of code required to define: 1. the protocol definition, 2. the delegate property in the controller, and 3. the implementation of the delegate method definitions within the delegate itself.
Need to be careful to correctly set delegates to nil on object deallocation, failure to do so can cause memory crashes by calling methods on deallocated objects.
Although possible, it can be difficult and the pattern does not really lend itself to have multiple delegates of the same protocol in a controller (telling multiple objects about the same event)
The "use case" for delegation is pretty much the same as for inheritance, namely extending a class behavior in a polymorphic way.
This is how the wikipedia defines delegation:
In software engineering, the delegation pattern is a design pattern in object-oriented programming where an object, instead of performing one of its stated tasks, delegates that task to an associated helper object. There is an Inversion of Responsibility in which a helper object, known as a delegate, is given the responsibility to execute a task for the delegator. The delegation pattern is one of the fundamental abstraction patterns that underlie other software patterns such as composition (also referred to as aggregation), mixins and aspects.
There are, obviously, many differences between delegation and inheritance, but the biggest one is, IMO, that inheritance is a fixed (aka, compile-time) relationship between two classes, while delegation can be defined at run-time (in languages that support this). On the other hand, inheritance offers better support for polymorphism.
Delegation is a huge topic (as inheritance is), and you can read a lot about it. In the end, deciding whether using delegation or inheritance comes down to deciding whether you want an "is-a" or and "has-a" relationship, so it is not so easy to list guidelines for choosing that.
For me, basically, the decision to create a delegate comes from the observation that:
my code presents a set of homogeneous behaviors (homogeneous here means that can be recognized as having a common "nature");
those behaviors might be be "customized" for particular cases (like in, replaced by alternative behaviors).
This is my personal view and a description of the way I get to identify "delegation" patterns. It has probably much to do with the fact that my programming discipline is strongly informed by the principle of refactoring.
Really, IMO, delegation is a way to define "customization" points for your class. As an example, if you have some kind of abstract workflow, where at each step you take some action depending on certain condition; and furthermore those concrete actions could be replaced by other of another kind, then I see there the chance of reuse through delegation.
Hope this helps.
My situation:
ClassA may or may not have a parent of type ClassB. Therefore saying [instanceOfA.superview somethingClassBSpecific]; is half hazardous. Plus, Xocde will get pissy, for good reason.
Is the recommendation here to dispatch a notification, or do some logic on the superview, e.g.,
if([objectOfA.superview respondsToSelector:somethingClassBSpecific] != nil){
//...
}
Or create a delegate of type ClassB where the situation permits?
As is so often the case, it depends. Using the view hierarchy, notifications, and delegation are three different ways that objects can communicate with each other. Deciding which of those (if any) is most appropriate requires thinking about how the objects in question are related to each other.
Notifications provide very loose (nearly zero) coupling between objects. They also provide one-to-many communication -- you post a notification, and every object that's listening for that notification will get the message. But notifications aren't always appropriate; communication is mainly in one direction only, and abusing the notification mechanism can lead to performance problems.
Delegation gives you a way to customize the behavior of an object. The most obvious example is the application delegate. Most every iOS application is based on the same class: UIApplication. UIApplication is exactly the same for every app even though each app does its own thing. The application object uses a delegate to provide the customization that gives the application its unique behavior.
The view hierarchy is another way that (some) objects are connected to each other. If the behavior you're implementing is a) part of a view and b) dependent on that view's relationship with other views, then it may make sense to use the superview and subviews properties.
So, what kind of functionality are you trying to implement?
This depends on your logical model. If you have an instance of a class implementing a protocol with optional methods, then using respondsToSelector: is appropriate when you are trying to call one of these optional methods. If you want the method you call to be required, create a do-nothing "guard" in the classes that you pass. Both techniques are valid, it's only a matter of whether or not you'd like your users to be conscious of the need to implement a specific method.
OK so I'm trying to get started with Xcode and I have some experience with OOP in general but mostly I'm used to scripting. Anyhoo, I'm trying to get a handle on some concepts in objective C and xcode and I'm having some problems putting everything together.
For starters, I'm having trouble understanding what delegates and protocols do. I think it would be useful if someone could explain this with a simple analogy of a postman, or a teacher, or a factory or something. I don't understand the difference between a method in a delegate and a regular class methods.
Say I have a Class Postman. Now postman has methods sortMail() and deleteMail(). What's an example of a delegate method. And if a delegate is used, where is the data returned? Inside the delegate? Do I have to instantiate the delegate and then read results from it or does the delegate kinda give the results back to the calling object? Where do protocols come in...
Simple examples please :) Baby steps.
Protocols and Delegates go together frequently. It helps to understand what a protocol is first.
Protocol
A protocol is a way of having a class promise to implement a standard set of methods.
Example: A certified electrician has a certain set of skills that all certified electricians will have. If you need someone to do something that a certified electrician is certified to do, then any certified electrician should be able to do it (in theory at least).
Delegate
Now a delegate is an object that has been given a responsibility to fulfill certain requirements. One object can be given the responsibility of fulfilling a need of another object.
Example: When building a house, the house needs to have wires run etc. This responsibility has been given to a certified electrician, and we know he can do it because he's certified (i.e. implements a certain protocol).
Putting it all together in a Cocoa context:
A UITableView needs cells supplied so it can display them. To supply the cells, a class will need to be created (or at least specified) which implements the UITableViewDataSource protocol. That guarantees that the class does the needed things to supply the UITableView with the needed cells.
So the UITableView delegates the responsibility of providing the cells to a certain class object which implements the protocol which guarantees that the object knows how to supply the needed cells.
Example
A delegate is an object that handles particular functionality for another object - as in "Object A delegates certain functionality to object B".
For instance, you may use an instance of Apple's class NSURLConnection to make a request for a web service, but Apple's code obviously won't know what to do with the data it downloads, so you provide a delegate object to handle that functionality. NSURLConnection then delegates that functionality to your object by passing it messages when it needs to do something like handle the data it downloads.
Another example is a table view. Apple have written a lot of code to display table views and handle interactions with them, but it doesn't know what data you want to display or what needs to be done with that data when somebody interacts with it. So you can provide delegate objects for these things. When a table view needs to know what data to display, it asks your delegate to fetch the data for it. When the user selects an item, it asks your delegate to handle it.
A protocol is simply a way of describing what messages the delegate is supposed to understand. There can be informal protocols, where it's just described in the documentation, and formal protocols, which are defined in a header file.
for example the UIPickerView, in the tutorial that i am learning i had to include the datasource and delegate protocols in my project for the pickerview to work. how would i know on other objects?
In general that is explained in the documentation of the individual object. For example http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIPickerView_Class/Reference/UIPickerView.html
In the Overview section it explains that, "the delegate must adopt the UIPickerViewDelegate protocol" and that, "the data source must adopt the UIPickerViewDataSource protocol"
From http://developer.apple.com/iphone/index.action just type the name of the object you are interested in into the search box and the documentation should explain everything needed to make it go.
To note, the UIPickerViewDelegate/Datasource are representative of the Delegate design pattern (see Cocoa Design Patterns) and are repeated throughout the Cocoa UI hierarchy as a method of modifying behavior of an object without having to subclass. It's quite graceful, less entropic, fosters the single responsibility principle, and reduces coupling. The delegation pattern is seen throughout all of Cocoa, not just the UI classes, so you can expect to see it often.
To know about other objects, you pretty much have to visit the Framework Library Reference for the specific class at the Apple Developer Center or from within the help system of Xcode. You can almost presume that all data backed UI objects will have datasource (delegate) methods, and most UI objects will have delegate methods.