What is the difference between Delegate and Notification?
Short Answer: You can think of delegates like a telephone call. You call up your buddy and specifically want to talk to them. You can say something, and they can respond. You can talk until you hang up the phone. Delegates, in much the same way, create a link between two objects, and you don't need to know what type the delegate will be, it simply has to implement the protocol. On the other hand, NSNotifications are like a radio station. They broadcast their message to whoever is willing to listen. The radio station can't receive feedback from it's listeners (unless it has a telephone, or delegate). The listeners can ignore the message, or they can do something with it. NSNotifications allow you to send a message to any objects, but you won't have a link between them to communicate back and forth. If you need this communication, you should probably implement a delegate. Otherwise, NSNotifications are simpler and easier to use, but may get you into trouble.
Long Answer:
Delegates are usually a more appropriate way of handling things, especially if you're creating a framework for others to use. You gain compile time checking for required methods when you use protocols with your delegates, so you know when you compile if you're missing any required methods. With NSNotificationCenter you have no such guarantee.
NSNotificationCenter is kind of "hack-ish" and is frequently used novice programmers which can lead to poor architecture. A lot of times these two features are interchangeable, but more "hardcore" developers might scoff at the use of the NSNotificationCenter.
Q: what is the reason for using "id" and what is the difference of them?
A: Using id
allows you to send any object to the method as a parameter. Note that you can not send primitives such as bools, floats, doubles, ints, etc. unless they are wrapped in their respective Object wrappers.
classB{
-(void)DelegateMethod;
}
and then call this in
classA{
classB delegate;
-(void)viewdidload{
[self.delegate DelegateMethod];
}
}
The above example you provided would require that classA
's delegate always be of type classB
, which isn't advantageous. Instead of using delegates in this scenario, you would probably just use a variable that referred to your other class, say, myClassB
. The beauty of delegates is that you can pass around any object, and the code just works as long as they implement the required methods (which the compiler ensures, as long as it's marked as the correct delegate type).
A delegate uses protocols and creates a has-a
relationship between the two classes. One of the other benefits of delegates is that you can return something back to the owning class.
Notifications, on the other hand, are more geared towards point to multipoint communication. An example of using an NSNotification
might be in a tab bar controller application, where you may need to notify multiple view controllers of a particular event so they can refresh data, etc. This is great for classes that have no knowledge of one another and it wouldn't make sense if they did.
Now, to your other questions:
Why do we use id
?
In your class, you want a handle to an object of indeterminate type, but which implements the protocol you define. Take UIWebView
, for example. There can be infinitesimal types of classes that can be a delegate for it, therefore, it should not name a specific type of class, but specify that the class must implement the UIWebViewDelegate
protocol. This reduces coupling to an absolute minimum and creates a highly cohesive application where you are creating interaction based on behavior, not state.
So, let's run through an example:
@protocol ClassADelegate
- (NSString*) determineValue;
@end
@interface ClassA : NSObject
{
id<ClassADelegate> delegate;
}
// Make sure you are using assign, not retain or copy
@property (nonatomic, assign) id<ClassADelegate> delegate;
@end
The implementation of ClassA
:
import "ClassA.h"
@implementation ClassA
@synthesize delegate;
- (void) somePrivateMethod
{
if (self.delegate && [self.delegate implementsProtocol:@protocol(ClassADelegate)])
{
NSString* value = [self.delegate determineValue];
// Do other work
}
}
- (void) dealloc
{
delegate = nil;
}
@end
In the header, we declare that the class will implement the ClassADelegate
protocol:
#import "ClassA.h"
@interface ClassB : NSObject <ClassADelegate>
{
}
- (void) someMethod;
@end
In the implementation of ClassB
we create an instance of ClassA
and set B
as the delegate of A:
#import "ClassB.h"
@implementation ClassB
- (void) someMethod
{
ClassA* aClass = [[ClassA alloc] init];
aClass.delegate = self;
// Other work and memory clean up of A.
// Some logic occurs in A where it calls the delegate (self) which will
// call the `determineValue` method of this class.
}
// Here's the delegate method we implement
- (NSString*) determineValue
{
return @"I did some work!";
}
@end