一. 引入PRotocal与delegate概念的目的
由于“id”类型的使用,无法通过id,获得真正想传递或接收的数据类型(虽然可通过id的自省机制,在运行时询问)。 因此我们在代码中说明,想要这个id类型的对象实现哪些方法(语法上的定义,有无protocal,编译器生成的代码是无区别的)。
id < Protocal > obj
声明对象obj,是一个id类型的对象,并满足某条件(Protocal)。
id < Protocal > obj =[ [MyClass alloc ]init ]
MyClass 承诺实现Protocal中的方法。
二. iOS中protocal的应用
1 delegate 和dataSourse
一个iOS中得对象,想完成某些重要的功能,和不属于类方法的方法,则它会把这些事件的操作代理出去,由它的代理完成。为了达到对上述的目的,在此对象中声明一个满足一系列方法(protocal)的属性,代表其代理。
1.1 可用于对子类中实现不属于类方法的方法(This is an alternative to subclassing to provide non-generic behavior)
举例:
1 // NetWorkManager.h 2 @protocol NetworkDelegate 3 @required 4 - (void)task:(NetWorkFlag)tag didSuccess:(NSDictionary *)result withInfo:(NSString *)infoString; //成功回调 5 - (void)task:(NetWorkFlag)tag didFailed:(NSString *)failedReason; //失败回调 6 @optional 7 - (void)setProgress:(float)newProgress; 8 @end 9 @interface NetWorkManager : NSObject<ASIHTTPRequestDelegate> 10 @property (nonatomic, weak) id<NetworkDelegate> networkDelegate; 11 .....//其他类接口
上述代码说明, NetWorkManager将其 didSuccess 与 didFailed 方法代理出去,由其代理 id<NetworkDelegate> networkDelegate实现。其中networkDelegate可以是任何类型(id)的对象,其承诺实现 @protocol NetworkDelegate。
1 //GetOrderController.h 2 @interface GetOrderViewController : TTBaseViewController <UITableViewDelegate,UITableViewDataSource,UIAlertViewDelegate,NetworkDelegate>
1 // GetOrderController.m 2 3 [self.networkManager setNetworkDelegate:self];
1.2 在对象(MVC)直接进行盲通信
举例:View无法拥有自己的数据,需要不断询问别的对象,进行通信。而View不想与某一特定类型的对象绑定,所以该通信对象最好是一个id(不可见)。
GetOrderController中有tableView属性,用于展示列表信息,即GetOrderController承诺实现dataSourse协议中得方法。此种情况下,tableView与GetOrderController的通信(controller与view)即盲通信(blind)。通信内容在此处为 count和dataAt两类。