Whenever I wanted to inform something to parent class, I have used delegate instead of calling directly parent's functions. I have implemented like this...
eg:
CustomClass *custom = [[CustomClass alloc] init];
// assign delegate
custom.delegate = self; // Here we are giving parent instance like normal method call.
[custom helloDelegate];
In custom class, I have intimated parent like below....
-(void)helloDelegate
{
// send message the message to the delegate
[_delegate sayHello:self];
}
So my doubts , how does it differ from direct call?. Setting delegate variable with self is somewhat equal to giving the parent instance to child and let the child call the function whenever required, how does protocols help here or why do we need protocols? what is the advantage?
thanx
A working example of the advantage of using a delegate as opposed to using a direct relation.
Say you are writing a universal app. You have two view controllers in your code iPadViewController and iPhoneViewController and they both need to get data from a web service. So you create a class for you web service call webServiceDownloaderClass.
Now, both your view controllers need to be notified when the webServiceDownloaderClass has finished.
Your options here...
Option 1 strong coupling
In you iPadViewController you define a method - (void)webServiceDidGetArray:(NSArray *)array;. And in the iPhoneViewController you define the same method.
In order for the webServiceDownloaderClass to call these methods it now needs a reference to each of the controllers...
#property (nonatomic, strong) IPadViewController *iPadController;
#property (nonatomic, strong) IPhoneViewController *iPhoneController;
and then when it finishes it needs to determine which one to call...
if (iPadController) {
[iPadController webServiceDidGetArray];
}
etc....
The cons here are that the view controllers are sort of defining what the web service class does when it is finished. Also, if you add another controller you have another property and no actual guarantee that the controller you referenced actually has the method you are trying to call.
Option 2 delegation
In your we service class you define a protocol.
#protocol WebServiceDownloaderDelegate <NSObject>
- (void)webServiceDidGetArray:(NSArray *)array
#end
and a delegate...
#property (nonatomic, weak) id <WebServiceDownloaderDelegate> delegate;
Now you are defining the actions of the web service class in the web service class. And you only need one reference to any class wants to be the delegate. Also, any class can be the delegate. So now both the iPad and iPhone controller can be the delegate and by conforming the the protocol they are "promising" the web service class that they will implement the required method - (void)webServiceDidGetArray:(NSArray *)array;.
Of course, this is just one case where delegates can be useful.
There are also cases for when you should possibly use a direct relationship rather than delegation.
your question is really about the difference between subclassing rather than implementing protocols (or interfaces in other languages like java)..
with delegates, you are implementing a protocol.. (which is a contract between the class referencing the delegate and the delegate itself).. this gives you more flexibility than subclassing because with subclassing you are automatically inheriting all the methods in the superclass (which is far more restricting than simply using some of the methods of another class.. in other words: subclassing = is a relationship.. whereas as implementing a protocol (same as delegation) = has a relationship.
if you read any book about design patterns.. they will talk extensively about the advantages of loose coupling your code and writing code that prevents modification but allows extension etc etc.. basically using delegation rather than subclassing is one way of fulfilling those design best practices.
A delegate call is not different from an ordinary method call!
What is different is how things are used, and this has nothing to do with the call mechanism. Delegates are used to decouple the definition of the code providing the delegate service from the code "consuming" the delegate service, so that the "consumer" (which, oddly, is usually a service on behalf of the delegate provider) does not have to be coded to know about THAT SPECIFIC delegate provider.
In Objective C delegates are commonly implemented using "protocols", but this is far from the only use of protocols. Objective C uses them extensively in providing common interfaces among the various Cocoa classes.
And, in limited circumstances, one can legitimately implement a delegate using a common superclass rather than a protocol.
If you have two classes that are part of the same development effort and which would not be likely to ever be used apart from each other, there is no need to employ the delegate "pattern" to facilitate communication between them, even though they are is a service-consumer/service-provider relationship. The only reason to do so would be "on spec", in case the "service" were ever reused unchanged in a different project.
Related
In my iOS app, many ViewControllers will need to send/receive data from a server based on user input and actions. I am going to use NSURLSession for all my networking activities. But I don't want to make every ViewController conform to the NSURLSession delegate
protocol and repeat all the methods.
I see two solutions
Create a class that conforms to the NSURLSession delegate
protocol. Other classes create an instance of this class and use its methods to send/receive data from the server. The reuse of the class handling all the networking will be done using singleton design pattern by overloading its init method so that only instance of it is created.
Disadvantage of this approach seems to be that having singletons make its tough to create unit tests that completely gets functionality of each class isolated form others. I.e.Suppose an error only happens because viewcontroler1 asked "shared class" to send a particular message followed viewcontroller 2 asked it send some other message. Then it is not possible to catch this using unit tests.
Subclass of the UIViewController that implements the methods and subclass my ViewControllers of of this.
One issue here is that if I have different kinds of views in app, then I need to create subclass for each type of ViewController with NSURL session delegate methods. And I have to carefully assign the delegate object from method to method. When I look at it, I think this approach also has the same unit-testing problem as approach 1.
I would appreciate any comments on
1. Approaches others have used in similar situation
2. Pros/cons of above approaches (including the 2 I have listed above). I realize this may be a bit subjective, but IMHO getting good advice on design patterns is as important as (or even more important than) answers to what is wrong with my code or which API to use to solve problem X
The way I've done this in the past is:
1) Created a class that contained a NSURLSession object
#interface CustomSession : NSURLSessionDelegate
#property (nonatomic, strong) NSURLSession *mySession;
2) In the CustomSession init method initialize mySession, set delegate to self.
3) Implemented desired NSURLSession delegate methods in CustomSession.
4) Use block methods (optional, but I prefer them)
5) Decide whether you want to use CustomSession as a singleton or instantiate it every time you need it. You can actually do both just define init methods accordingly.
+ (CustomSession *)session
{
//Singleton
}
+ (instancetype) newClient{
//normal init method}
6) As for unit testing, you could have a weak pointer in CustomSession to the parent VC (as you pointed out this would work if you're not using a Singleton).
Quick suggestion: Use AFNetworking, will simplify your life. For example I use AFHTTPSessionManager and the corresponding block methods provided:
[self GET:detailsURL parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject)
I have class called ViewController. How to make this class is a sub-class of "metaiosdkViewController" and "JWslideViewController". Help me with syntax.
i have written like this
#interface ViewController : MetaioSDKViewController,JWslideViewController
but this giving me error
objective-c doesn't support multiple inheritance,but if you want to add some extra behaviour you can achieve it through delegates..
yes objective-c doesnt support multiple inheritance but you can give one parent so
#interface ViewController : MetaioSDKViewController
and
#interface MetaioSDKViewController : JWslideViewController
this is just an idea I know you can implement well as per your need
What is it that you want to achieve with multiple inheritance?
Do you want to override methods from each of these super classes?
Note that objective c provides 2 mechanisms for extensibility:
1) Implementing a Protocol and make your object the delegate:
#interface ViewController : <MetaioSDKViewController,JWslideViewController>
This enforces ViewController to implement certain methods as defined in contract by 2 delegates, and at some point in processing, they get called. If you don't implement them, they may simply not be called but you may not get desired functionality.
Example: UITableViewDataSource protocol that defines many methods that UITableViewController subclass implements. cellForRowAtindexPath is very famous example of a delegate method that your own table view subclass must implement to draw your own custom cells.
Note that this is not the type of extensibility that subclasses provide in general sense. Your class does not extend any functionality here. Rather it becomes what it says - a delegate - someone who is assigned to do some task. Like you do:
yourTableView.delegate = self; //tell self to be the delegate of yourTableview
Library code does it's stuff and in some point in processing it calls [delegate someMethod]. If your own class implements it, it calls it, otherwise delegate will be nil, and it may just be NO-OP and you don't get desired functionality. Again, this is implementation-dependent. Maybe the protocol defines that the method is compulsory, in which case your class MUST implement this method in order to compile.
2) Implement a category:
This is sort of a shortcut way to extend library classes. They act like an extra stub which, when your code runs, attaches itself to the already existing memory layout of the library objects and provides extra functionality.
You can define a category on any of the in-built classes as well. In fact that is the primary objective it is used for. For example, here is an NSString category which provides HTML conversion. There are hundreds of categories implemented as open source and they provide enormous benefits where library code falls short. Discussing their suitability in entirety is however out of scope for this discussion.
One thing to note however is: You do not override anything using a category. Rather you are supplying something in extra. For example if you want some custom drawing across all your app views, you can define a category on UIView in your project and then all your views could simply include the category header file. You don't even have to inherit from this category, you simply inherit from the base type.
e.g. in the NSString category example above, you do not have to define your NSString to be of type NSString+HTML. Instead you just include the responsible NSString+HTML.h file wherever you want those extra methods like stringByConvertingHTMLToPlainText and so on. The changes remain limited to your project - to the files where you include this category.
Categories do not provide for extra data members - and that is something that only inheritance can provide. Yet, multiple inheritance among viewcontrollers is something you should definitely reconsider hundred times - you will see that what you are looking for is not multiple inheritance.
I'm really confused about the concept of delegates and protocols. Are they equivalent of interfaces and adapter classes in Java? How do they work?
None of the resources I've read were helpful so far.
"Delegation is a simple and powerful pattern in which one object in a program acts on behalf of, or in coordination with, another object. The delegating object keeps a reference to the other object—the delegate—and at the appropriate time sends a message to it." I have no idea what this means.
Can someone please explain what they are and give a simple example? Thanks in advance!
EDIT:
As far as I now understand,
1) delegates implement protocols (another name for interfaces)
2) object registers a delegate (that implements a protocol)
3) object can call protocol methods on the delegate
Therefore, a delegate is connecting the object with the protocol.
Please correct me if I'm wrong.
I still don't understand why the object itself can't implement a protocol? It could've been so much easier!
Protocols are a way to specify a set of methods you want a class to implement if it wants to work with one of your classes. Delegates and Data Sources like UITableViewDelegate and UITableViewDataSource are protocols indeed.
You specify a protocol this way:
#protocol MyProtocol <NSObject>
- (void)aRequiredMethod;
#required
- (void)anotherRequiredMethod;
#optional
- (void)anOptionalMethod;
#end
Methods declared after the #required or before any other specifier are required and the classes that want to use your protocol need to implement all of them. You can also declare some optional methods by declaring them after the #optional specifier.
You then can specify that a class "conforms" to a protocol (implements the required methods) in the interface of the class:
#interface MyClass <MyProtocol>
#end
You usually keep a reference to an object conforming to a protocol using a property. For example, to keep track of a delegate:
#property (nonatomic, weak) id<MyProtocol> delegate;
At this point, in your code, you just have to call the method you want to call on the object that you're keeping reference of and that implements your protocol as you would with any other method:
[self.delegate aRequiredMethod];
To check whether an object conforms to a protocol you can call
[self.delegate conformsToProtocol:#protocol(MyProtocol)]
To check whether an object implements a method you can call
[self.delegate respondsToSelector:#selector(anOptionalMethod)]
For more information, check the Apple's guide Working With Protocols.
A protocol which declared with the (#protocol syntax in Objective-C) is used the declare a set of methods that a class that "adopts" (declares that it will use this protocol) will implement. This means that you can specify in your code that, "you don't care which class is used so long as it implements a particular protocol". This can be done in Objective-C as follows:
id<MyProtocol> instanceOfClassThatImplementsMyProtocol;
If you state this in your code, then any class that "conforms" to the protocol MyProtocol can be used in the variable instanceOfClassThatImplementsMyProtocol. This means that the code that uses this variable knows that it can use whichever methods are defined in MyProtocol with this particular variable, regardless of what class it is. This is a great way of avoiding the inheritance design pattern, and avoids tight coupling.
Delegates are a use of the language feature of protocols. The delegation design pattern is a way of designing your code to use protocols where necessary. In the Cocoa frameworks, the delegate design pattern is used to specify an instance of a class which conforms to a particular protocol. This particular protocol specifies methods that the delegate class should implement to perform specific actions at given events. The class that uses the delegate knows that its delegate coforms to the protocol, so it knows that it can call the implemented methods at given times. This design pattern is a great way of decoupling the classes, because it makes it really easy to exchange one delegate instance for another - all the programmer has to do is ensure that the replacement instance or class conforms to the necessary protocol (i.e. it implements the methods specified in the protocol)!
Protocols and delegates are not restricted only to Objective-C and Mac/iOS development, but the Objective-C language and the Apple frameworks make heavy use of this awesome language feature and design pattern.
Edit:
Please find this Example. In the UIKit framework of Cocoa Touch, there is a UITextFieldDelegate protocol. This protocol defines a series of methods that classes which are delegates of a UITextField instance should implement. In other words, if you want to assign a delegate to a UITextField (using the delegate property), you'd better make sure that this class conforms to UITextFieldDelegate. In fact, because the delegate property of UITextField is defined as:
#property(nonatomic, assign) id<UITextFieldDelegate> delegate
Then, the compiler will give warnings if you assign a class to it that doesn't implement the protocol. This is really useful. You have to state that a class implements a protocol, and in saying that it does, you're letting other classes know that they can interact in a particular way with your class. So, if you assign an instance of MyTextFieldDelegateClass to the delegate property of UITextField, the UITextField knows that it can call some particular methods (related to text entry, selection etc.) of your MyTextFieldDelegateClass. It knows this because MyTextFieldDelegateClass has said that it will implement the UITextFieldDelegate protocol.
Ultimately, this all leads to much greater flexibility and adaptability in your project's code, which I'm sure you'll soon realise after using this technology! :)
In it's simplest form a delegate is an object which receives messages from another object. And you do it all the time.
So say you had car object with an engine.
#interface car : NSObject
#property (nonatomic) id engine;
#end
So could forward a start message to the engine.
[_engine start];
The engine is acting as a delegate, you're just passing it a message.
Protocols make it more formal, and Xcode will check that you are conforming to the required or optional methods.
#property (nonatomic) id <engineDelegate> engine;
says that the engine object MUST contain the function start because in the the protocol definition it asked for it.
#protocol engineDelegate
- (void) start;
#optional
- (double) fuelLevel;
#end
Why are delegates and protocols so cool? Well because the engine could be any number of different engines which you could use at runtime, it could be a jet engine, a combustion engine, a phasing modulating engine it doesn't matter, as long as it conforms to the protocol. And you tell Xcode that it does conform by adding the delegate to the class interface.
#interface timeWarpDrive : NSObject <engineDelegate>
I've been struggling with delegates for a long time. It's a very hard concept for me for some reason. I feel like now I have more knowledge, but I'm still far from being confident.
Please tell me if any of these are incorrect/incomplete and why. Thank you.
Delegates implement protocols (unimplemented method headers)
An object (a delegator) can register a delegate (that implements a protocol). This can be done by declaring a property of type id that implements a protocol:
#property (weak, nonatomic) id <MyProtocol> myDelegate;
The delegator can call certain methods (as specified in MyProtocol protocol) on the delegate
Any class that implements the protocol and has to be Delegator's delegate, can declare itself as such:
MyDelegator* myDelegator = segue.destinationViewController;
myDelegator .delegate = self;
Advantages of using a delegate:
a. Reduces coupling (Delegate and Delegator are no longer dependent on each other) which is an important OO design principle
b. makes Delegator more generic; it can now work with other objects, not just this Delegate
1,2 - yes
3 - can call any method of MyProtocol,
4 - correct.
5 - almost right, a very good explanation can be found here delegate and controllers
Yes. But the protocols can be informal.
Yes.
Yes.
Yes and no. Again, the delegate could implement the methods informally... but then you'd want the delegator to verify if the delegate respondsTo (or implements) a method before calling it.
The delegate doesn't necessarily need to set itself as the delegator's delegate (in fact, it shouldn't). Analogy: A business specialist comes to my company and tells my boss to delegate the administrative paperwork to his secretary. The secretary (the delegate) didn't tell the boss (the delegator) to give it work... a third-party did.
A delegate doesn't have to register itself as the delegate (again, it shouldn't). It needs only be able to do the work. Normally the delegate would know nothing (no pointers to) the delegator. So the delegate wouldn't have MyDelegator* myDelegator = segue.destinationViewController;, no.
A) Yes!
B) Yes. Essentially what "reduce coupling" is;
Adding a C): It also allows you to change the behaviour on-the-fly by simply changing the delegate at runtime.
I understand what a delegate does in iOS, and I've looked at sample code, but I'm just wondering about the advantages of this type of encapsulation (as opposed to including delegate methods in the primary object).
The advantage of the delegate design pattern is loose coupling. It enables class A (the delegate) to depend on class B (the delegating class) without class B having to have any knowledge of class A. This ensures that the dependency relationship is one-way only, rather than being circular.
It also forms the foundation (lower case "f") of Apple's frameworks because it allows them to invoke your code as appropriate when functionality specific to your application is required. For example, responding to a button tap or telling a table view how many sections there should be.
Delegation is a design pattern not only used in iOS but many other languages. It enables you to hand values and messages over in your class hierarchy.
In iOS, delegation requires the "delegate" class to implement a protocol which contain methods that the "delegating" knows about. Still following?
The delegating class's implementation will call these protocol methods, but the delegate class will implement these methods in their class.
This keeps your Classes clean.
In reality, you don't really need delegation if you can add new methods to a single class. But for UIKIT's UIView class, Apple will not allow you to add new implementations to their class.
correct me if I'm wrong.
The most common use of a delegate in iOS is to establish communication within modules that are unrelated or partially related to each other. For example, passing data forward in a UINavigationController is very easy, we can just use segue. However, sending data backwards is little tricky. In this case, we can use delegate to send the data backward.
Let's call, the class, associated with the first Controller ClassA and the class, associated with the second Controller ClassB. The first Controller is connected to the second controller with a forward segue. We can pass data from ClassA to ClassB through this segue. Now, we need to pass some data to ClassA from ClassB for which we can use delegates.
The sender class(ClassB) needs to have a protocol in its header file(.h) and also a reference of it as delegate inside the block, #interface ClassB .... #end. This reference let's the ClassB know that it has a delegate. Any class that wants to use this ClassB will have to implement all of this protocol's required methods(if any). So, the receiver class,ClassA will implement the method but the call will be made by the sender class, ClassB.
This way, receiver class doesn't need to worry about the sender class' internal structure, and can receive the required information.
Delegation as I understand it is when an object will pass the responsibility of handeling an event to another object thus "delegating" the responsibility to that object.
For example if you have an NSButton in iOs you generally assign the Delegate to be the parent view controller. This means instead of handeling touchUp events in the definition of the button it is instead handled in the view controller.
The main advantage of delegation over simply implementing methods in the "primary object" (by which I assume you mean the object doing the delegating) is that delegation takes advantage of dynamic binding. At compile time, the class of the delegate object does not need to be known. For example, you might have a class that delegates the windowDidMove: method. In this class, you'd probably see some bit of code like
if([[self delegate] respondsToSelector:#selector(windowDidMove:)]) {
[[self delegate] windowDidMove:notification];
}
Here, the delegating class is checking at runtime whether its delegate responds to the given method selector. This illustrates a powerful concept: the delegating class doesn't need to know anything about the delegate other than whether it responds to certain methods. This is a powerful form of encapsulation, and it is arguably more flexible than the superclass-subclass relationship, since the delegator and the delegate are so loosely coupled. It is also preferable to simply implementing methods in the "primary object" (delegating object), since it allows runtime alteration of the method's implementation. It's also arguable that this dynamic runtime makes code inherently more dangerous.
Delegate is an important design pattern for iOS app.All apps directly or behind the hood use this delegate pattern.
Delegate design pattern allows an object to act on behalf of another.
If we are working with tableview then there are "tableViewDelegate" and "tableViewDataSource". But what this means
Suppose you have a tableview.
now some major concern for this.
1.what is the datasource(the data that will appear in table view) for this tableview?
2.How many row for table view etc.
delegate design pattern solve these question using another object as the provider or the solver of these question.
An object mark himself to the table view and ensure the table view that "Yes i am the man who can assist you" by marking himself as the delegate to the table view .Thanks
The class marked as delegate takes the responsibilities to handle the callbacks sent while some event occurs. For example, in case of UITextField, there are some methods called when some events occurs like editing started, editing ended, character typed etc. These methods will already be defined in the protocol. We will have to assign delegate for that i.e. which class is going to handle these events.
With the help of a delegate, two-way communication can be achieved. A delegate might be used to make an object reusable, to provide a flexible way to send messages, or to implement customization.
In iOS ecosystem especially UIKit Framework which consists of UIApplication, UITableView, UICollectionView, UITextfield & so on uses delegate & datasource design pattern intensively to communicate data to and fro.
Delegate design pattern is used to pass/communicate data from FirstVC(Delegator) to SecondVC(Delegate) to complete a task.
Here, SecondVC(Delegate) conforms to a protocol delegate & implements all its requirements like methods by providing body to complete that task given by FirstVC(Delegator).
Also, FirstVC(Delegator) object will be having a optional property of protocol delegate type i.e delegate which must be assigned by SecondVC(Delegate).
Now, FirstVC(Delegator) can call that method residing in SecondVC(Delegate) by passing data from its delegate property.
EX: CEO(FirstVC) which passes data i.e "confidential data" to Secretary(SecondVC) to do further processes using that data.
Datasource design pattern is part of Delegate pattern which is used to pass/communicate data from SecondVC(Delegate) to FirstVC(Delegator) when a task is assigned to SecondVC(Delegate).
Here, SecondVC(Delegate) conforms to a protocol datasource & implements all its requirements like methods with return type by providing body to talk back to FirstVC(Delegator) after the task is given by FirstVC(Delegator).
Also, FirstVC(Delegator) object will be having an optional property of protocol dataSource type i.e dataSource which must be assigned by SecondVC(Delegate).
Now, FirstVC(Delegator) can call that method with a return type residing in SecondVC(Delegate) by passing data from its dataSource property.
EX: Secretary(SecondVC) replies back with a data i.e "Sir, I am already having too much work to do. Please, can you assign that data to others" to CEO(FirstVC). Now, CEO(FirstVC) will analyse that data to do further processes.
Delegation means one object passes behaviour to another object..