The protocol in OC (PROTOCOL) is similar to the interface in. NET (Interface), which is simply a list of a series of methods that can be implemented by any class. The difference is that in. NET, if a class implements an interface, it must implement all the methods declared in the interface, but in OC, you can not implement all the methods declared in the protocol, need some functions, to implement the corresponding method.
This pattern is generally referred to as the proxy mode . In iOS and OS X development, Apple employs a number of proxy models to decouple view (UI controls) and controller (controllers) in MVC.
Monitoring idea: If you want an object to be able to listen to the action of a control, you can let the object implement a specific protocol, good abstraction ~. Speaking, for example, if you want the user to click on a button, the app can do something (for example, back to the previous screen), you need to set the Listener Listener button's Click event, and then "go back to the previous screen" This thing will be given to the listener to do. Because you need to make a specific response, not all objects can be the listener for the button. What kind of object can act as a listener for a button? The condition is: Implement a method in a protocol (this Protocol is generally declared within the object that needs to be monitored).
Take the Click event of the Listener button as an example:
Button: I can be a bit, who will listen to me ah?
//Button.h header file
//Same as classification Catelogy, the agreement can also be written in other files, but generally written in the .h file
#import <Foundation/Foundation.h>
@class Button;
// <> represents the realization of a certain protocol
@protocol ButtonDelegate <NSObject>//The protocol can also implement other protocols. The defined protocol implements the most fundamental protocol NSObject
-(void)onClick:(Button *)btn;//This method is reserved for objects that need to implement the protocol to call
@end
@interface Button: NSObject
@property (nonatomic, retain) id<ButtonDelegate> delegate;//The button should provide a property to set the listener, the delegate is the listener of the button, otherwise the button and its listener cannot communicate
//No thread safety is required, so it is nonatomic; it is an object, it is best to use retain; I don’t know that the declared type of object will become its own listener, so id
-(void)click;//This method is called by the button itself to simulate the button click event, calling this method is equivalent to clicking the button
@end
//Button.m implementation file
#import "Button.h"
@implementation Button
-(void)dealloc {
[_delegate release];
[super dealloc];
}
-(void)click {
// If _delegate implements onClick: this method
if ([_delegate respondsToSelector:@selector(onClick:)]) {
// When the button is clicked, the listener should be notified. And tell the listener which button was clicked
[_delegate onClick:self];
} else {
NSLog(@"The listener does not implement the onClick: method");
}
}
@end
ButtonListerner: I want to listen to you!
//ButtonListerner.h header file
#import <Foundation/Foundation.h>
// Declare the agreement in advance, which is consistent with the purpose of @class
@protocol ButtonDelegate;
@interface ButtonListener: NSObject <ButtonDelegate>//To be a Button listener, we must implement the protocol set by my Button
@end
//ButtonListerner.m implementation file
#import "ButtonListener.h"
#import "Button.h"
@implementation ButtonListener
-(void)onClick {//Implement the onClick method prepared for me in the Button protocol
NSLog(@"ButtonListener has listened to the button being clicked");
}
@end
main: Let me check to see if ButtonListerner can monitor Button.
//Realize button monitoring in main function
#import <Foundation/Foundation.h>
#import "Button.h"
#import "ButtonListener.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
// initialize a button
Button *button = [[[Button alloc] init] autorelease];
// initialize a button listener
ButtonListener *listener = [[[ButtonListener alloc] init] autorelease];// Set the button listener
button.delegate = listener;
NSLog(@"button:%@", button);
// Click the button
[button click];
}
return 0;
}
The result printed after the main function runs is: ButtonListener has monitored that the button is clicked.
This shows that the onClick method in ButtonListerner is called. Strangely, we did not call this method in the main function. This is the result we want: when "[button click];" is executed (as mentioned earlier, this means that the Button is clicked), then certain things are automatically processed (for example, the onClick method in ButtonListerner here). Just a few more words.
Understand this monitoring process, mainly pay attention to these two methods:
-(void)click method: This method is implemented by the button itself, which is equivalent to the occurrence of an event;
-(void)onClick: method: This method is implemented by the agent.
The above example shows that when the button Button calls its own click method, the onClick method of the button's agent ButtonListener is also called, so that the purpose of monitoring the button click event is achieved. In other words, when we want a button to be clicked, other places can perform some various operations, we do not need to implement it inside the button, it is enough to implement it inside its proxy object. To achieve the purpose of decoupling.
The protocol can also be written in a newly created protocol file, and the objects that implement the protocol can selectively implement the methods in the protocol. Which methods must be implemented, and which methods can be selectively implemented? It depends on how the method is declared.
Define two protocols:
//StudyDelegate.h protocol file
#import <Foundation/Foundation.h>
@protocol StudyDelegate <NSObject>
// The default is @required
-(void)test3;
// @required indicates the method that must be implemented
// Although literally it must be implemented, the compiler does not force a certain class to be implemented
@required
-(void)test;
-(void)test1;
// @optional means optional (can be realized\or not realized)
@optional
-(void)test2;
@end
//LearnDelegate.h protocol file
#import <Foundation/Foundation.h>
@protocol LearnDelegate <NSObject>
@end
Define a student class, objects of this class are used to implement the above protocol:
//Student.h
#import <Foundation/Foundation.h>
@protocol StudyDelegate, LearnDelegate;
@interface Student: NSObject <Study, Learn>
@end
//Student.m
#import "Student.h"
#import "StudyDelegate.h"
#import "LearnDelegate.h"
@implementation Student
@end
Determine whether the object of the Student type implements the protocol:
#import <Foundation/Foundation.h>
#import "Student.h"
@protocol StudyDelegate;
int main(int argc, const char * argv[])
{
@autoreleasepool {
Student *stu = [[[Student alloc] init] autorelease];
// Note: OC is a weak grammar, not strict requirements on the type
// NSString *stu = [[[Student alloc] init] autorelease];
// [stu stringByAbbreviatingWithTildeInPath];
// conformsToProtocol: Determine whether a certain protocol is complied with
if ([stu conformsToProtocol:@protocol(StudyDelegate)]) {
NSLog(@"Student has complied with the Agreement of StudyDelegate");
}
// respondsToSelector: Determine whether a method is implemented
if (![stu respondsToSelector:@selector(test)]) {
NSLog(@"Student did not implement the test method");
}
}
return 0;
}
The result of the operation is: Student complies with the StudyDelegate protocol; Student does not implement the test method; verifying the statement just now: the protocol can be followed, but the method declared in the protocol is not implemented. Compliance with the agreement means the realization of the agreement.
Note that selector is equivalent to method (message), and sending a message is to call a method.
Objective-C: Simulate button click event to understand proxy mode