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.
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.
Can anyone simply explain delegating pattern and callback function in objective C.
Or can point to some documents (with Easy and Basic Explanation) which can make these concepts clearer to me. As i am not getting any idea about it from any book or website or (Apple Developer)references.
All the resources i have come across to understand this, makes me more confuse by using the terminology which i find hard to digest.
Any Help Appreciated.
I will try to explain the value of delegation with one example.
Say you have a table; the table will show some rows. Suppose now, you want to customize the way this table react to some event, e.g., the selection of a specific row.
One common way of doing this in OOP is subclassing a table base class and overriding some methods there.
With delegation, you don't need subclassing the table base class; rather you use the base class and tell it to "forward" some messages to some other object. This is the basic idea.
In our example, when the row is clicked, the table base class does not know what do except sending a message to one object that you specify as the delegate to carry through that action.
So, one basic advantage of delegation is that you do not need to subclass. Another advantage you have is that a delegate can act as the delegate for several other objects. Indeed, if you have a look at the generic declaration of a delegate method, you will see that the first parameter is the object that is delegating:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
so when the delegate receives the message, it knows who sent it and with which object it should interact.
The example I gave you about the table shows one kind of delegation, which I would not compare to callbacks. Anyway, delegation can be used as well as a kind of advanced calling-back-scheme.
Take the class NSURLConnection; it can be used to manage aynchronous communication.
Async communication is the typical case where callbacks are used.
With NSURLConnection, the delegate pattern is preferred; so, instead of specifying a callback (a function, which has to be a static function, or a static class method), you specify an object. This object implements the methods that a protocol defines (NSURLConnectionDelegate protocol); you can see those as a whole set of callback functions. When the NSURLConnection has some data ready, it will call a method of the interface, e.g., – connection:didReceiveResponse: to notify that it has received the response.
In such case, the point is not avoiding subclassing, rather it is a more flexible callback mechanisms (allowing for better encapsulation, basically).
I hope this helps clarifying the two concepts...
delegate noun |ˈdeligit|
A person sent or authorized to represent others, in particular an
elected representative sent to a conference.
A delegate in the Cocoa Touch frameworks such as Foundation or UIKit is a separate object instance that is entrusted to listen in to, and optionally decide behaviours on behalf of the delegator.
Take the example of UIWebView. The web view can entrust responsibility onto one delegate as long as that instance conforms to the UIWebViewDelegate protocol, that is promises to behave as the web view expects a delegate to behave.
The delegate gets called from time to time. Embedded in the delegate method names is information about what the call is about.
webView:shouldStartLoadWithRequest:navigationType: - Tells the delegate that the webview wants to load a request, and ask the delegate if it should do so.
webView:willStartLoad: - Tells the delegate that the web view will start loading a page, and it is too late to do anything (This is a hypothetical method that is not actually available, I use it as a consistent example).
webView:didFinishLoad: - Tells the delegate that the web view did load a page and it is now finished.
The value of using delegation is that you do not need to sub-class UIWebView in order to tweak how it behaves. One objkect can also serve as delegate to many different webviews, or even serve as delegate to many different kinds of classes.
A normal UIViewController subclass probably conforms to many delegate protocols, for example UITableViewDelegate to respond to selections in a table, UIActionSheetDelegate to respond to selection from an action sheet, etc.
In Objective-C they make a big deal about delegates and make it seem like they're somehow special, but they're simply objects that get called. The only difference is the way they're used: You pass a class instance pointer to some service, and it calls back through specified methods of that instance when it needs some action or data from your code (very much similar to the callback scheme used in other languages).
"Protocols" are just a way to define the methods used in a delegate arrangement. It's a "poor man's multiple inheritance" scheme, virtually identical to the "interface" concept in Java.
But because "protocols" are available, you can (but don't have to) make your delegate class the same class as, say, your view controller. This simplifies your design in many cases (data can be easily shared, etc), but it's not at all mandatory to "share" a class that way, vs using a unique class for the delegate.
I have a UITextView that points to the File's Owner as its delegate, and I have a number of the delegate functions implemented. However, I would also like to point to a second object (in this case a TextExpander object, http://www.freshblocks.com/tutorials/how-to-add-textexpander-touch-sdk-to-iphone-apps/) also as a delegate. How might this be possible? As far as I know there can only be one delegate in objective-c.
I don't know the specific of TextExpander but he delegate design pattern assumes one and only one delegate. You can't have two delegates for one object.
There are ways around this. You could designate one of the delegates as the primary delegate and implement all the methods in this class. That class could then simple call the secondary delegate for the required methods. This is the simplest approach but does result in the primary delegate becoming tightly coupled with the secondary delegate.
Another approach would be to resolve the messages dynamically and use message forwarding. You would still require the a primary/secondary delegate pattern, but instead of the primary delegate needing to implement all the methods it would simply pass all messages it doesn't respond to onto the secondary delegate. This approach means that the secondary delegate can change by adding/removing additional delegate methods without having to change the primary delegate. The key method is - (id)forwardingTargetForSelector:(SEL)sel. See Objective-C Message Forwarding for a good explanation.
It seems that they solve this in step 5, by setting [textExpander setNextDelegate:self]; before setting the textExpander object as the "primary" delegate of the view.
I don't have the code myself so I haven't tried it, though, and their documentation is... well not.
Just for information: Delegates are not an Objective-C feature, but a design pattern using though Cocoa/Cocoa-touch.
Delegate pattern allow only one object to be notified of the changes of another. The solution to have an intermediate delegate object could be an easy way of doing things.
If you want to keep your code clean and reduce the coupling you might use another pattern known as KVO (Key Value Observing). Apple provides a good guide on how to use it.
In KVO a single object, that needs to be KVC (Key Value Coding) compliant, can notify multiple objects without even knowing about it. It uses an intermediate notifier object (singleton for you application).
Check the Apple doc on KVC + KVO and you shall be able to do what you want.
I have a class with the protocol NSXMLParserDelegate implemented. I call this ParserHelper. I parse a lot of XML which happen to have some tags in all of them and i have about 20 parsers (one for each type of XML), and i didnt want to implement it over and over again.
So, I subclassed my ParserHelper class 20 times, adding in each subclass the required tags/behaviours like CaseAParser, CaseBParser and so on...
I just implement the delegate methods i needed and called it on the superclass once i'm done with the method.
I assume it works on every delegate.
This way, all you need is to make your class a subclass of SMTEDelegateController and implement the methods you need, remembering to call the [super whatEverMethod:andParameters] at the end of your functions and you should be good to go.
I have 2 or 3 views in my iPhone application where I have various pieces of functionality that use delegates. In all cases the delegates are assigned to "self", responding specifically to that view's actions and interacting with instance variables.
However, if I do something that takes a bit of time with a delegate, and leave the view, obviously it crashes my app as the delegate methods get called on a view I've left.
Typically in my delegate methods I am doing things like interacting with IBOutlets, calling other instance methods, saving data to Core Data etc...
How can I work with delegates better? Is what I'm doing typical, or not?
Thanks for any guidance!
Depends on the use case. If, for example, you've got a UINavigationController that manages a ViewController that use something such as Location Services, when you pop the View Controller off of the stack you're going to want to set the CLLocationManager's delegate to nil. You can do this in the dealloc method.
Can you give a specific example of an issue you're facing?
I've encountered this situation once when dealing with MapKit (race conditions involving delegate callbacks and delegate deallocation). However, in general, I think it's an indication of a bad design decision when your delegate becomes invalidated as a result of race conditions, but I could be wrong.
Typically, the objects that make use of your delegate should exist within the context of the delegate itself. So, for example, the same class that contains various IBOutlets that you want to manage with delegate callbacks should also be the delegate of those IBOutlets. That way, when the class (i.e., the delegate) is deallocated, the IBOutlets are (hopefully) also deallocated, so they won't be making callbacks to anything.
bpapa's right. More generally, if you have a potentially lengthy delegate callback, either make sure that 1) the delegate is an object that won't be deallocated during the lifecycle of the delegator (e.g., UINavigationController managing UIViewControllers) or 2) the delegator's delegate object is set to nil during the delegate's deallocation.
... That last sentence was a mouthful. :)
Your delegates should be declared as
#property (nonatomic, assign) id <MyDelegateProtocol> delegate;
This ensures a weak reference so that when you dealloc the object which has delegate, it only removes the reference and NOT the corresponding object. using (strong) will cause a crash on dealloc.
When calling your delegate, you can check
if (self.delegate && [self.delegate respondsToSelector:#selector(MyDelegateProtocolCallbackMethodName:)] {
[self.delegate MyDelegateProtocolCallbackMethodName:result];]
}
Generally I use delegates for proxy classes which fetch data from a server or edit screens like changing the title of a task in a todo list or editing a model in a database.
The advantage of a delegate is a very clear use case. If you find that multiple parts of your app need to be aware of when an event happens (triggered on 1 screen but perhaps listened for in another), I suggest using NSNotificationCenter to raise notifications, instead of or perhaps in addition to sending a message to your delegate.
I think I've understood what that Delegate is supposed to do. If a class conforms to that protocol, it tells the underlying system: "Hey man, I am the UIApplication object's delegate! Tell me what's up, and I may tell you what to do!".
What, if multiple classes implement that? Is that possible? Does that make any sense?
While you could implement multiple classes that conform to the UIApplicationDelegate protocol only one, the first, would receive these messages.
Implementing a protocol to create a delegate is only one part of the equation. That delegate then has to be registered with the code that's generating the messages and these systems generally only support one delegate.
In the case of UIApplication you can change the delegate using the 'delegate' property in the UIApplication shared class but this will replace the original delegate, not add an additional one.
If you need to broadcast UIApplication level messages to other systems then this is functionality you should add to your existing delegate.
You can implement multiple classes that adopt the UIApplicationDelegate protocol, but only one can be the actual delegate at any given time. It's set by [UIApplication sharedApplication].delegate, which is normally set up by the main NIB file by an outlet connection.
Just conforming to the protocol doesn't set your object as the delegate, you need to do that explicitly either in the nib or in code. As already mentioned, only one object can be a delegate at one time. Having multiple delegates may make sense in some cases-- for example if you have a table view that displays two sets of data, you could make two delegate and datasource objects for it, and switch between them as needed. It probably doesn't make sense to do this for the application's delegate though, since the code there is pretty specific.
Keep in mind that sometimes an object will send notifications in addition to calling delegate methods. A lot of time it looks like they're the same thing, since the object will automatically subscribe your delegate to the notification if it includes a certain method signature. The key difference though is that other objects besides the delegate can also subscribe to these notifications, so you can hook them up to multiple objects at once.
As Daniel Dickson stated:
You can implement multiple classes that adopt the UIApplicationDelegate protocol, but only one can be the actual delegate at any given time. It's set by [UIApplication sharedApplication].delegate, which is normally set up by the main NIB file by an outlet connection.
... but know that you can swap these out at runtime if you need to. I recently looked at using this technique as a way of merging two applications developed by different parties that could not share source code or refactor; yet needed to co-locate under a single icon on the device.