概念
简单来说就是一系列方法的列表,其中生命的方法可以不饿任何类实现,这种模式一般称为代理(delegation)模式。不就是C#的接口噻。OC叫协议,代理和监听器思想是一样的。
在iOS和OS X开发中,Apple采用了大量的代理模式来实现MVC中View(UI控件)和Controller(控制器)的解耦。
--------------------------------------
在OC中协议中的协议不会被强制实现
---------------------------------------
创建一个按钮类Button
写协议的潜规则:ButtonDelegate
Button.h
@protocol ButtonDelegate <NSObject>
//<实现某个协议>(分类):继承
-(void)onClick;
@end
@interface Button:NSObject
@property (nonatomic,retain) id<ButtonDelegate> delegate;
// click button;
-(void)click;
@end
Button.m
#import "Button.h"
-(void)dealloc{
[_delegate release];
[super dealloc];
}
-(void)click{
//button is click then inform listener.
[_delegate onClick];
}
--------------------------------------------
创建一个普通的类ButtonListener
ButtonListener.h
// #import "Button.h"
@protocol ButtonDelegate; ->对协议进行提前声明 与@class用途一致
@interface ButtonListener:NSObject<Buttondelegate>
@end
ButtonListener.m
#import "ButtonListener.h"
#import "Button.h"//因为用到协议的方法 所以必须import
-(void)onClick{
NSLog(@"The button is clicked.");//deal with you want to realize on click
}
main.m
#import "Button.h"
#import "ButtonListener.h"
Button *button= [[[Button alloc]init]autorelease];//initialize button
ButtonListener *buttonListener = [[[buttonListener alloc]init]autorelease];
//initializa a listener
botton.delegate=listener; //set listener to button
//click button
[button click]; // simulate the button is clicked
ButtonListener.m
----------------------
总结,button 有一个delegate
监听器有好几个,只要监听器实现这个delegate的onClick方法,就可以监听button,自主选择。
通知监听器的唯一方式就是调用监听器的对象。
-----------------------------------------------
但是这种情况下,监听器和按钮没有锁定什么的,两个按钮都可以用这个监听器,所以就是不知道监听的是哪个按钮?所以在写监听器的时候当按钮被点击要告诉监听器哪个按钮被点击了。。
因此改为
---------------------------------------------------
Button.h
@class Button
@protocol ButtonDelegate<NSObject>
-(void)onClick:(Button *)btn;
@end
@interface Button :NSObject
@property (nonatomic,retain) id<ButtonDelegation> delegation;
-(void)click;
@end
Button.m
-(void)dealloc{
[_delegate release];
[super dealloc];
}
-(void)click{
//按钮被点击了,应该通知监听器,并且告诉监听器哪个按钮被点击了。
if([_delegate respondToSelector:@selector(onClick:)]){
[_delegate onClick:self];
} //如果delegate有实现onClick:这个方法 再调用
else{
NSLog(@"监听器并没有实现onClick:方法");
}
}
@end
---------------------------------------------------------
但是第二个监听器没有实现带参数的代理
//unrecognized selector sent to instance 某个对象没有这个方法 你硬要调用时就会产生这个错误
-------------------------------------------------------------
//ADD
ButtonListener.m
-(void)onClick:(Button *)btn{
NSLog(@"ButtonListener 可以监听到按钮-%@被点击了",btn);//内存地址
}
-0------------------------------------------
设计监听器原则:
那个对象触发监听器,就把那个对象传过去