views:

1030

answers:

4

I know a good bit of Objective-C and I'm working on a iPhone SDK book (coming from a Obj-C book that just did console programs). It attempted to explain delegates though it was rushed and didn't really understand what it was trying to convey. I'm a little confused on what they are and when you would use them.

Basically it said they are classes that take responsibility for doing certain things on behalf of another object.

Anyone care to elaborate?

Thanks!

+1  A: 

A good way to understand delegates is through example. One example is UITableView (or NSTableView, depending on whether we're talking iPhone or Mac OS). Either way, the table view has a delegate and a dataSource (both of which act as auxiliary objects to the receiver).

Instead of UITableView handling the events when, for example, one of its rows is tapped by a user, it instead tells its delegate "Hey! I've been tapped on this row and this section, do what you will!". Typically the delegate is a Controller of some sort, which implements the correct method. So the table view (after checking to see if the delegate actually has a definition for the method) sends a message like this:

[delegate tableView:self didSelectRowAtIndexPath:indexPath];

Since your Controller is the table's delegate, and it implements that method, it decides what to do. When the method completes (in this case it should just return void), then execution continues on the table view.

Delegates are a concept. It's not a language feature of Objective-C. The delegate member of UITableView is like any other object. Although, delegates typically are not retained, they are instead assigned (to avoid retain cycles).

They are very handy when you get the hang of them. I suggest practicing with examples like TableViews (NSTableView, like I said earlier, works in a similar way, just with different methods).

jbrennan
So they are a class that an Object calls upon when something is done to itself. And depending on what was done to itself it calls a certain method from the delegate's class. Correct?Is their a proper way of creating a delegate class, or is it just another ordinary class with methods that other classes happen to call upon?
Technically, the delegate is an object. You could have fifty instances of an object which implements some delegate methods, but only the instance that gets set as the delegate has its methods called.The proper way of creating a delegate is to define a protocol, which defines a set of methods that must/can be implemented.
johnw188
@Avizz: You're right, a delegate can be any kind of object you want. Although typically it will be one which `conforms to a protocol`. If an object conforms to a given protocol, it basically means "I promise I have implemented everything required of me in the given protocol`. This way, when an object sends a message to a delegate, they have confidence the delegate knows what to do.
jbrennan
Another thing make sure I'm correct on...When say a cell is clicked, it uses a instance of a delegate object and sends it a message. The delegate class has a method to deal with what it's received and the method based on the information it has received does something? Correct?
@Avizz: Correct. In my table example, when the cell is selected, the table then prepares an object called `indexPath` (which says which row was selected) and then passes that to the delegate in the method call above. So `delegate`, which could be as simple as an NSObject subclass, implements the method above. When the table calls it, with that indexPath, then our delegate performs the method, using the indexPath, does its thing, and returns `void`. Delegate methods don't have to return `void`, but this one does. Some return a bool, some return floats (cell height for example), etc.
jbrennan
Data sources are not delegates.
bbum
@bbum: Correct, I'll clarify.
jbrennan
+2  A: 

Let's say you want to present the user with an alert, and you want a method to run when the user touches one of the buttons. The problem is, how do you know what method to call, on which object, when someone touches a button?

In order for a class to be a delegate, you have to declare it as such. In the above example, lets say you have an ApplicationController object which controls the flow of your application. In the declaration, we would say

@interface ApplicationController : NSObject <UIAlertViewDelegate>

This tells the compiler that ApplicationController is going to implement some methods in the UIAlertViewDelegate protocol. We look that protocol up in our documentation, and see a list of methods. As we want to do something when a button is pressed, we see:

alertView:clickedButtonAtIndex: - Sent to the delegate when the user clicks a button on an alert view. This method is optional.

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

So, if we implement a method in ApplicationController called alertView:clickedButtonAtIndex, create an ApplicationController object, and then set that object as the delegate of an alert we show, everything is set up. As soon as someone presses a button on the alert, the alertView:clickedButtonAtIndex method will be called, passing in the alertView and the index of the button pressed.

This allows you to do whatever you want with that information. A simple case statement:

if( buttonIndex == 0 ) {
    _myString = @"Pressed the button";
} else {
    _myString = @"Pressed the other button";
}

The Objective-C reference docs are very, very good, and all the delegate protocols are pretty self explanatory.

johnw188
what does the at symbol mean ?
Stefano Borini
It depends on which one you were referring to. You can define strings in place by saying @"string here", which is an objective c syntactical thing. Otherwise, @interface is a class declaration.Lots of objective c specific things begin with @, as it's never used in C/C++ identifiers. It allows the developers of objective c to ensure there's no confusion as to whether something is from C/C++ or objective c
johnw188
+7  A: 

Think of delegates as inversion the direction of dependencies. In most frameworks the clients will inject the required dependencies into instances, usually in the constructor or by setters.

Cocoa does the reverse; instances instead request the data when and if it is needed.

There are four main types of delegate methods:

  • Conditionally before - Signals something is about to happen, but the delegate may abort. Name always include the word Should.
    Example: searchBarShouldEndEditing:.
  • Unconditionally before - Signals something is about to happen. Name always include the word will.
    Example: applicationWillTerminate:.
  • Unconditionally after - Signals something has happened. Name always include the word did.
    Example: applicationDidFinishLaunching:.
  • Customizers - Request information for how to function. Name includes the information that is required.
    Example tableView:viewForHeaderInSection:.

All delegate methods always has it's sender as one of the arguments. Any delegate method may have a return value that alters how the sender behaves.

PeyloW
By far best explanation among these answers, imho
Toon Van Acker
A: 

Take a look at my tutorial on the delegate design pattern here: http://www.jonmsterling.com/blog/?p=74. I hope that helps.

Jonathan Sterling