I usually read a word 'delegate' in the apple document and their library book. What exactly meaning about this word? Any special meaning in iPhone?
Thank you very much.
Delegates are a design pattern in object-oriented languages that allow an object to "call out" to unknown code to perform activities or calculations that that object cannot effectively do on its own. Let's say you have a class Dog:
#protocol DogDelegate;
#interface Dog : Wolf <Domesticated>
- (void)bark;
- (void)tiltHeadAdorably;
- (void)playWithToy: (Toy *)aToy;
#property (readonly) Toy *favoriteChewToy;
#property (readwrite, assign) id <DogDelegate> delegate; // "DELEGATE" PROPERTY DECLARED HERE
#end
The delegate object is generally supplied by the code that instantiates Dog, and is called upon by that instance to do things that the dog itself can't do. For instance, consider this interface of the DogDelegate protocol, which defines what the Dog's delegate object is expected to do:
#protocol DogDelegate <NSObject>
#required - (void)letDogOut: (Dog *)aDog;
#required - (void)letDogIn: (Dog *)aDog;
#optional - (void)scratchDog: (Dog *)aDog forTimeInterval: (NSTimeInterval)duration;
#end
In this case, an instance of DogDelegate is often the owner of the Dog (and, in Objective-C, a delegate often owns an object, so this lines up nicely with the metaphor.) The dog, when it needs to go out for... dog activities... will ask its delegate to perform the -letDogOut: method, placing the dog in the backyard. When done, it will ask its delegate to perform the -letDogIn: method, bringing the dog back inside. When the dog wants affection, if its delegate is able to, it will ask the delegate to scratch it for some period of time using -scratchDog:forTimeInterval:.
Delegate is a Design Pattern that Apple adopts heavily. In a nutshell, think of it like "I'm responsible for handling ...". Where ... is a notification, event, protocol, etc. For example, your AppDelegate is responsible for your handling your App setup, display, launch.
Please keep in mind I am over simplifying it. But I am sure someone can provide a much more detailed answer if you need.
A delegate is the same thing as a callback function in JS ( the exception being that delegates are type-safe.) For example, if you're doing Ajax in JS, you declare a callback function to be called when the Ajax call is finished. In this same fashion, you would declare a delegate function to be called, for example, when a song selection dialog is closed.
Delegate is a object that controls the whole application. It shows the main window and will tell the app what to do when it is launched and closed. It is basically the command center of your app. The best way to use this is to call other controllers to display some NIBS. There really isn't anything special about a delegate in an iPhone app, but there are special methods that are called.
Related
I have just been learning iPhone apps development but I have a hard time in understanding what delegate actually means? Can anyone tell me with example what it does and how important it is? Thanks for any helps!
It's a key concept to understand conceptually so getting your head around how to think about it ahead of the technical details is important. Simply put, a delegate is a callback.
Two main scenarios to use delegates:
A class or control wants to abstract out the details on how to do work (like retrieve data).
Allow others to hook code into a pipeline.
Examples:
UITableView - a table view is just a control that knows how to render a list of cells. It handles all the heavy lifting of rendering, scrolling, etc... But, it has no idea how to load your data. So you implement a datasource delegate which has methods to get the cell data for a given row etc... That makes it easy on you. You just use the control and plug in the specifics for your data. The UITableView will do everything for you ... just answer a few specific questions for. A delegate answers those few specific questions.
A text control - you add a text control to your view and voila! you can type in it and alls good. But what if you want to do something when they start typing or when they're done typing? Well, the text control offers a delegate with methods that allow you to hook into the execution pipeline of the text control. It allows the text control to do everything for you and allows you to interject code where you need it. Many times, there's way to interject code to make a decision on whether something is allowed. The control will call back and ask, should I be able to do x? You can interject code and influence the behavior.
If you're creating a control or class, you can create your own protocol, datasource delegates etc... so your control can focus on doing what's advertised. For example, let's say you wanted to create a task control. You could:
First, create a contract. Hey, if you're going to provide data for my control, these are the questions I'm going to ask you. I'll take it from there... In this case, I'm going to ask you the number of tasks and I'm going to have you give me a task given the row number.
#protocol XXTaskBoardDelegate <NSObject>
-(NSInteger*)getTaskCount;
-(XXTask*)getTaskForRow:(NSInteger*)rowNumber;
#end
In the control or class, give the consumer a way to give us the delegate datasource class that will answer the questions the control will ask. At this point, the control is a pure control. It knows nothing about how you get your data. It's asking for an object (id) that implements a contract/protocol. id
#implementation XXTaskBoard
- (void)setDelegate:(id<XXTaskBoardDelegate>)newDelegate
{
// the control stores the delegate so it can callback and ask you questions.
}
Then, for the delegate class, in the header declare you implement that formal protocol
and in the implementation m file you provide the code.
#interface AppController : NSObject<XXTaskBoardDelegate>
{
//...
}
then, implement it in the implementation
#implementation AppController
- (NSInteger*)getTaskCount
{
return [model queryTaskCount];
}
- (XXTask*)getTaskForRow:(NSInteger*)rowNumber
{
return [[model tasks] getItem:(NSInteger*)rowNumber];
}
A delegate is an object that another class can pass messages to. In practice delegate classes have to conform to a delegate protocol.
For instance we will take a subclass of a table view controller. This is a delegate for your table view. First you define that it is a table view delegate by doing this:
MyTableViewController : UITableViewController <UITableViewDelegate>
This says that class MyTableViewController is a subclass of UITableViewController and CONFORMS to the UITableViewDelegate protocol.
Setting [tableView setDelegate:self] (or defining it as such in IB) then passes the self object to the tableview in order for the tableview to send messages to it.
The main message it sends is the didSelectRowAtIndexPath message which tells your class that the user has pressed a table view cell.
So the object that takes the click event (the table view) passes on the message that the cell has been clicked to the delegate object (which in this case is your MyTableViewController object).
Delegate protocols exist so that you can make sure that the delegate object has the necessary methods to deal with your messages. Methods in a delegate protocol can be #optional or enforced. Any methods that are optional don't have to be defined. In your MyTableViewController class the method didSelectRowAtIndexPath is optional - you don't have to have it. If the table view doesn't find the method it just won't call it.
However the cellForRowAtIndexPath is necessary and without it your app won't compile.
I hope this helps and is straightforwards for you. If you need any more info let me know.
Delegates are just way of getting callbacks from something. You pass a delegate (a pointer to an object that conforms to a protocol) to something and when it has new data for you or when an event occurs that something make a method call on the delegate.
For example, when events occur, like your app is put into the background or the app is about to terminate the UIApplication object will call your application delegate to let it know. When a CLLocationManager has a new GPS position is will call your delegate to pass it the new position. UITableViews call their delegates to get UITableViewCells to display in the table. There are many uses of delegates in iOS.
Here is my dilemma. I would like to have a text box and a button. The user types in text and then presses the button. Once the button is pressed, a text message window (using MFMessageComposeViewController) comes up. I don't know how to set this up. The problem is that the TextBox will require a delegate (UITextFieldDelegate) and the MFMessageComposeViewController will require an MFMessageComposeViewControllerDelegate. How can I have a .h file that declares a view that is more than one delegate?
I'm new to iPhone programming so any help on how to have an interface view that handles more than one delegate (so that I can have multiple types of controls in my view) would be really helpful!
A delegate does not need to be a view. Indeed, in most cases it probably shouldn't be. Often you will make a controller object the delegate, although this depends a lot on what you're doing.
The delegate protocols you need (MFMessageComposeViewControllerDelegate and UITextFieldDelegate) are quite distinct, so a single object can readily implement the methods of both without any confusion. But even if you are the same delegate type for several objects, the methods will be passed a pointer to the calling object so you can decide what to do case-by-case if necessary.
If you just mean how do you declare your class as implementing both protocols, you would do this:
#interface MyDelegate : NSObject <MFMessageComposeViewControllerDelegate, UITextFieldDelegate>
{
...
}
...although this presupposes that the protocols are formally required, which I don't think is the case here. In which case such a protocol list is unnecessary.
Otherwise, I probably am not understanding your question...
EDIT: OK, it seems like what you're looking for is how to link up the delegates at runtime. This varies according to the particular class, but for MFMessageComposeViewController you do this:
MFMessageComposeViewController* composer = ...;
id<MFMessageComposeViewControllerDelegate>* delegate = ...;
composer.messageComposeDelegate = delegate;
Easy, no? In this case the protocol is required, so you'd have to include it in the interface as described previously.
In general, if an object uses a delegate for anything, it will have a property or a method to allow you to set it, which you'll find in the documentation. Eg, in this case: Properties for MFMessageComposeViewController.
Note that delegate properties are conventionally weak references, so the objects in question need to be retained somewhere in your application.
I am new to the iPhone development environment so be gentle:
Currently writing an iPhone game app that will also have a high score view. Was wanting to make this view so that it was on its own and I could call it from another class (.m file)
Question is, how do you call another class file? I know I need to include the header from that file, but how do I call a "function/message" from that class...something like updating the high score?
I hope this makes send. Thanks in advance for any and all help.
Geo...
You really should work your way through the introductory documentation on Apple's developer website:
Learning Objective-C: A Primer
and
Your First iPhone Application
If your function is static, call it like this:
[ClassName theFunction:parameter];
If your function is a member of the class, then create an instance of that class and call the function like this:
ClassName obj = [[ClassName alloc] init];
[obj theFunction:parameter];
Don't think of it as calling functions/methods/procedures/whatever. Think of it as one object talking to another. What do they need to do this? You need a reference to the object you want to talk to.
Often, you'll want to create an instance variable that gets assigned to the object you're interested in. If both objects are in a nib together, you can draw connections between them in Interface Builder. Otherwise, you'll need to structure your code so that they can find each other (e.g., give the nib's owner a reference to whatever other object needs to talk to the view).
You might want to try working through one of the many tutorials out there (for instance, on Apple's developer site) to get a feeling for how this works.
The preferred technique for this would be delegation. So that your main view delegates the task of scoring to your HighScore view.
#protocol myDelegate;
#interface myClass : UIView {
id <myDelegate> delegate;
}
#property (nonatomic, assign) id <myDelegate> delegate;
#end
#protocol myDelegate
- (void)myMethod //Method to be implemented by your High Score View
To implement this protocol in your High Score View do:
#interface HighScore : UIview <myDelegate>
The in your HighScore.m implement the method mymethod:
- (void)myMethod {
//update Score etc...
}
To call the method from your other view do:
myHighScoreView.delegate = self // self is your other view
[delegate myMethod] // calls the method in the other view.
I hope that's clear.
-Oscar
I'm working through an iPhone tutorial (link text and it has me put in some code (a few times throughout the various tutorials) but it doesn't explain it at all.
In this code:
todoAppDelegate *appDelegate = (todoAppDelegate *)[[UIApplication sharedApplication] delegate];
What exactly is an appDelegate? What does the "delegate" at the end of the instantiation mean? Actually, what does the whole thing mean? (UIIapplication sharedApplication)?
I am a .Net programmer if that helps someone explain it better. I hate learning through tutorials because I always need to know what EVERYTHING does and no one explains everything.
Let's back up a little bit.
The square brackets ([ ]) are Objective-C's method calling syntax. So if Cocoa had a C# syntax, the equivalent syntax would be:
TodoAppDelegate appDelegate = UIApplication.sharedApplication.delegate;
In C#, you would use a static class for a class that only has a single instance. In Cocoa, the Singleton pattern is used to accomplish this. A class method (in this case, sharedApplication) is used to retrieve the single instance of that class.
Delegates in Cocoa are not like the delegate keyword in C#, so don't be confused by that. In C#, you use the delegate keyword to reference a method. The delegate pattern in Cocoa is provided as an alternative to subclassing.
Many objects allow you to specify another object as a delegate. Delegates implement methods that those objects will call to notify them of certain events. In this case, UIApplication is the class that represents the current running application (similar to System.Windows.Forms.Application, for example). It sends messages to its delegate when things that affect the application happen (e.g. when the application launches, quits, gains or loses focus, and so on.)
Another Objective-C concept is the protocol. It is similar in principle to a .NET interface, except that methods can be marked as #optional, meaning they classes are not required to implement the methods marked that way. Delegates in the iPhone SDK are simply objects that conform to a specific protocol. In the case of UIApplication, the protocol delegates must conform to is UIApplicationDelegate.
Because it's not required to implement every method, this gives the delegate flexibility to decide which methods are worth implementing. If you wanted to, for example, perform some actions when the application finishes launching, you can implement a class that conforms to the UIApplicationDelegate protocol, set it as the UIApplication instance's delegate, and then implement applicationDidFinishLaunching:.
UIApplication will determine if its delegate implements this method when the application finishes launching and, if it does, call that method. This gives you a chance to respond to this event without having to subclass UIApplication.
In iPhone applications, developers also frequently use the app delegate as a kind of top-level object. Since you don't usually subclass UIApplication, most developers keep their global application data in the app delegate.
A delegate is just an object that implements certain methods (basically callbacks). The NSApplication docs explain what its delegate is supposed to do and what messages it needs to respond to to.
And this isn't instantiation. The snippet you posted above doesn't create anything. It accesses whatever object is set as the application's delegate. [UIApplication sharedApplication] gets the object representing the application, and sending delegate to the application gets its delegate (if any).
to add more to the mix of responses and another point of view, delegates are objects that can (but don't necessarily need to) do work for another object.
So let's say you have objectA, and can assign to it a delegate (let's call it delegateObject).
From objectA's point of view, there are certain bits of work that may need to be done. Depending on the context, the actual work and the results of such work can be different.
So instead of having objectA implementing a method for all these instances, we'll say... let's have another object, delegateObject, do the work... and as long as the results are returned in the proper format, we don't care what delegateObject did to get there.
objectA will first check that delegateObject exists and that delegateObject has implemented a method to do the work asked of it.
To accomplish this, NSObject (which every Cocoa object inherits from) has this method:
- (BOOL)respondsToSelector:(SEL)aSelector
and objectA would do a simple test before sending a message to delegateObject, for example:
if ([delegate respondsToSelector: #selector(someMethod:sender:)])
{
[delegate someMethod:#"stuff" sender:self];
}
and because objectA only sends a message to its delegate if one's been assigned, delegate is not retained by objectA.
if we were to use UITableView as an example, it has a lot of UITableViewDelegate methods. One of them is:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
every time the user touches a row in a table, the UITableView object will first check that there's a delegate, if there's a delegate, it'll then check that the delegate has implemented the above method. If it does, then it'll send the message to the delegate. This method expects no return value, and UITableView will go about its merry way, regardless of what the delegate does. And if there is no delegate that implements that method, then nothing happens.
I'm new to Objective-C and development on Apple's platforms, but hopefully I can frame this question in an understandable way regardless :)
I want to parse an XML feed for my iPhone app, and I decided instead of shoving all of the delegation methods from an instance of NSXMLParser into my view controller, I'd wrap this up inside of a FeedParser class. After reading a few docs and example code, here's what I came up with:
#protocol FeedParserDelegate <NSObject>
- (void)parserDidLoadEpisodes:(NSArray *)episodes;
#end
#interface FeedParser : NSObject {
id <FeedParserDelegate> delegate;
}
#property (nonatomic, assign) id <FeedParserDelegate> delegate;
- (id)initWithURL:(NSURL *)url delegate:(id<FeedParserDelegate>)theDelegate;
#end
Simple. Delegates of my FeedParser object just have to implement parserDidLoadEpisodes.
However, as I started actually making my FeedParser class use NSXMLParser, I realized that I didn't have to specify that FeedParser implements a protocol for NSXMLParser -- I could just implement the delegate methods that I wanted to do something with. I think I've noticed this with other classes that follow the delegate pattern, too, but not all.
So why wouldn't I too just not bother with specifying a formal protocol for my FeedParser class? It would cut away some perhaps unnecessary code. I guess the question is: why would I want to create a formal protocol instead of just doing something like just checking to see if the method is implemented on the delegate with respondsToSelector? Is it only so that the compiler will issue nice warnings if a required delegate method isn't implemented?
A protocol declared with #protocol is called a "formal protocol". The other way to do it is to declare a category (a set of additional methods) on NSObject, like so:
#interface NSObject (FeedParserDelegate)
- (void)parserDidLoadEpisodes:(NSArray *)episodes;
#end
Then simply define that method for any object that you want to be a feed parser delegate, and leave it undefined otherwise. This is called an "informal protocol".
Why are there two ways? Well, here's a hint: the informal protocols came first. What it comes down to is that they added formal protocols because informal ones weren't cutting it. Informal protocols make it too easy to forget an important method or try to use an object as a delegate for something it's not designed to work with.
Basically, for the cost of adding <FeedParserDelegate> here and there, you can get the compiler to do your debugging for you. The compiler will generate warnings for the most common delegate bugs, which saves you time if you make one of those mistakes. Why not take advantage of its helpfulness?
Always, always, always favor compile-time error checking over run-time. You could of course ask the class if it supports the method, but why ask when you can know?
The answer is no, you don't have to. But you should want to. :)
Adding a protocol makes the compiler check things for you. If you don't get those nice errors at compile time, then you'll get them later at run time when they're harder to track down.