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.
Related
I come from C# background, is it correct to say that delegates (not the C# version) in Swift are basically the same as interfaces in C#?
I see tutorials on using delegates in Swift, for passing data from one view controller to another view controller.
My question is this, can't one simply add a function to a swift class then have the view controller sub classed from that? Like
func ShowName(name : String)
And have the first view controller call the second controller using that
function (that is in the class that the second controller is subclassed from).
Technically, it is Swift protocols that are analogous to C# interfaces. A protocol is effectively a contract of what methods/properties a class will implement. Like C# interfaces, it can be used in delegation patterns, but it also has far broader applications.
But protocols serve a central function in delegation patterns (see Delegation discussion in The Swift Language or the Protocol or Delegation discussions in Cocoa Core Competencies), in which an object can designate another object with which it will communicate. The protocol simply outlines the precise nature of what an object requires of its delegate object, as well as what optional interfaces it supports with its delegate.
In answer to your question, when you have a delegate, you don't technically need to use a protocol, but it is best practice to do so. It makes the formal contract between the two classes very explicit, while at the same time keeping the two classes otherwise loosely coupled.
While it might take an extra two or three minutes up front to implement the protocol, it's almost always well worth the effort. It will simplify your maintenance of these classes in the future. So while you don't technically need to use protocols for your delegates and/or exchanging information between objects, I think you'll thank yourself if you do so.
You need delegates
No matter if you create some of your own you will not get around using them - they are builtin everywhere.
And yes, you could simply define a function in a viewController and call that one, but then the caller of that method has to now he is dealing with a viewController, nothing he really cares about. All he cares about is the fact that there is / has to be a function called showName.
If you are going to pass data forwards you do not have to use delegation since you know where you are going to pass the data to. But if you wan to pass data back you normally dont know where you came from -> second controller does not know and should not know he was presented by first view controller. He should work the same way no matter from where he got presented. And whoever feels responsible for him can and should assign himself as delegate which gets informed of changes or callbacks or whatever.
The subclassing you mention is basically that, but you can only subclass once, therefore if you want your class to be the delegate for a TableView, a CollectionView and your CustomView, you are going to have a bad time with only subclassing. What you are going to have to use is delegation via protocols
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.
Can any one differentiate when do we use Delegation over category and vice versa. I am clear over this.
Thanks
Category allows to add new methods or overwrite existing methods on a class, thus allows to extend a class without subclassing. Adding methods is the most useful aim, overwriting can go really wrong if you do not know exactly what the class being extended does.
It is more a language feature not a pattern, it works on each class.
Delegate is a pattern not a language feature, the class that is supposed to used must be coded for it, otherwise it won't work.
Usually a delegate will be required to implement a protocol known by the class that is going to receive the delegate. The class will then use the delegate to do stuff it was coded for, some of the most common are sending notifications, using a part of a strategy pattern, that is asking question in certain part of code to make decisions based on the concrete delegate's implementation, letting delegate execute an action or any combination of them.
For example UIApplicationDelegate is a notification (application:didFinishLaunchingWithOptions:) and action (application:openURL:sourceApplication:annotation:) protocol, UITextFieldDelegate is notification (textFieldDidBeginEditing:) and strategy (textField:shouldChangeCharactersInRange:replacementString:).
Actually I can imagine using category to implement delegating in all this cases I stated above: sending notifications, doing actions, taking part in a strategy. But it would require you to very very good know what to extended class is doing, probably to have it code, otherwise you can very easily break the class or be broken by changed class implementation. So this usage would be in my opinion highly wrong.
category: Adds methods to an existing class.
delegate: Modifies behavior of another object by allowing some other object, the delegate, to participate in the object's operation.
Say you've got an iOS application with three tables. Even though they're configured the same way, those tables each may behave differently if they have different delegates.
You can't do that with a category because a category applies equally to all instances of the class it extends. On the other hand, if you want to extend the UITableView class to add some new capability, you need a category*. Delegates are instance-specific and limited to the role envisioned for them by the designer of the delegating class.
*or a subclass, of course.
Categories are used when you need to extend the class without creating a subclass, for example when you need to add a method named isURL to the NSString you can make use of categories as follows, here we not creating a subclass, instead we are extending the implementation.
#interface NSString (Utilities)
- (BOOL) isURL;
#end
Delegates are similar to callback functions,
In cocoa-touch development...
Use AppDelegate for delegate classes
Create separate delegate class and locate in new .h/.m for each class need to use delegate
Use view controller classes(whenever such exist) to do that job for all
classes managed by this controller
What would you recommend?
Well it depends. The entire concept for delegate protocols exist so that you can have a lot of flexibility. Sometimes you take the simply default route but sometimes you need to be able to have a lot of different delegate classes.
(1) App delegate -- the app delegate should only be used for UIApplicationDelegateProtocol methods or delegates for actual properties of the delegate instance itself. In other words, if the app delegate doesn't directly deal with an instance e.g. the application object, then the app delegate should serve as the instance's delegate. Piling up extranous methods in the app delegate will muddle the app and make it snarlingly interconnected and difficult to debug and maintain.
(2) Wholly separate delegate classes are usually used when you have (A) a large number of delegate protocols to implement or (B) you have the same protocol to implement for multiple instances but require a different behavior for each object's delegate. E.g. you have several UITextFields each of which behave differently. You create as separate delegate class for each so that each text field has it's own custom implementation of the delegate protocol's methods.
(3) Using the controller for delegates is the easiest, most logical and most modular way to go in the majority of cases. In many cases such as UI elements the delegate methods need an awareness of other UI elements which the controller can provide.
In sum, never do (1) as a general parking place for any random delegate methods and default to (3) in the majority of cases.
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.