协议:
OC中的协议,类似于JAVA中的接口,用来规范接口。协议可以被多重继承(和JAVA中的接口完全相类似),oc和java和c++中一样不能多重继承,所以如果要实现多重继承,那么就可以用协议。
//协议中声明的方法,有两种权限
@required:(缺省)必须的,即遵从协议的类,必须实现这个方法
@optional:可选的,遵从协议的类,如果实现了这个方法,必须出卖,如果没实现也没关系。
创建一个MyProtocal的协议
//声明一个协议
@protocol MyProtocal <NSObject>
//
-(void)bark;
@end
#import "MyProtocal.h"
@interface Dog :NSObject <MyProtocal>
//Dog遵从协议Myprotocal,则Dog的对象都遵协议
-(void)bark;
-(void)shakeTail;
@end
@implementation Dog
-(void)bark
{
NSLog(@"won!");
}
-(void)shakeTail
{
NSLog(@"shaking tail");
}
@end
main.m
#import <Foundation/Foundation.h>
#import "Dog.h"
int main(int argc,const char * argv[])
{
@autoreleasepool {
Dog *dog=[Dognew];
id<MyProtocal> obj=nil;//这是遵从协议Myprotocal的ID指针,只能指向遵从同样协议的对象
obj=dog;//代理对象,遵从协议的对象不需要用强引用指向
//指针只能接受协议上声明过得消息,不能接受协议上没有声明果的消息。
//例如:
[objbark];//可行
// [obj shakeTail];//不可行,因为该方法在协议中没有声明,当然并不会直接报错,因为obj就是Dog对象指针,但是这样的写法是不符合OC的语法的。所以尽量不要使用。
[dogrelease];
}
return 0;
}
协议的重要用处,一个是规范接口,一个是实现代理
代理:
代理是完成两个对象间通信的一种机制。一个对象发送数据给另一个对象。
代理多用于传值通信:正向传值和反向传值。
【注】代理是实现两个类的对象间通信的一种机制。
【委托方】主动方 持有带协议的id指针,可以使用协议。
【代理方】被动方 遵从协议,实现方法。
代理离不开协议,是有协议的支撑,才能谈代理的。代理通俗的来说就是一个对象【委托方】中没有做这个事情的方法,但是又不得不完成这件事情,所以,它就制定了一个协议,规范了方法的声明,然后有另一个对象【代理方】遵从了这个协议,具体的完成了这个事情。所以此时委托方对象就委托代理方来完成这件事情。
一个对象发送数据给另一个对象。
代理分为正向传值和反向传值
//正向传值
这儿有这样一个例子,一个广播站,它只负责发送广播,并没有接受广播的方法,然后它制定了一个协议,规范了接受广播的方法为playVoice,(那么遵从这个协议的类,都有这个方法,因为这个方法的属性是@required,是必须实现的,所以遵从协议的类必须实现这个方法。)这时候收音机来了,它说我可以接受广播,但是广播站并不知道收音机接收广播的方法是什么,所以它得让收音机遵从它制定的协议,然后“建立代理”(委托方委托代理方,按照委托方同一的接口方法完成任务)。这样收音机就完成了接受广播的任务。
#import <Foundation/Foundation.h>
@protocol BordcastDelegte <NSObject>
@required
-(void) playVoice:(NSString*)newVoice;
@end
@interface Bordcast :NSObject
@property(assign)id<BordcastDelegte> delegte;
-(void)startBordcast:(NSString*)newVoice;
@end
#import "Bordcast.h"
@implementation Bordcast
-(void)startBordcast:(NSString*)newVoice
{
[self.delegteplayVoice:newVoice];
}
@end
#import <Foundation/Foundation.h>
#import "Bordcast.h"
@interface Radio :NSObject<BordcastDelegte>
@property(copy)NSString* ID;
@end
#import "Radio.h"
@implementation Radio
-(void) playVoice:(NSString*)newVoice
{
NSLog(@"%@:%@",self.ID,newVoice);
}
@end
#import <Foundation/Foundation.h>
#import "Bordcast.h"
#import "Radio.h"
int main(int argc,const char * argv[])
{
@autoreleasepool {
Bordcast *bordcast=[[Bordcastalloc] init];
Radio *radio4=[[Radioalloc] init];
radio4.ID=@"radio4";
//建立代理对象
bordcast.delegte=radio4;
[bordcaststartBordcast:@"hello world"];
[bordcastrelease];
[radio4release];
}
return 0;
}
回调,类似于嵌入式中的“定时器和中断”,即某个主方法在运行中,将一个任务交给另一个方法完成,但是主方法并不知道这个方法什么时候完成,所以当这个方法完成后,应该自动的告诉主方法已经完成这个任务了。在项目实际开发中,用到的地方,有一个主线程,开启一个副线程去下载图片,主线程接着做自己的事,直到副线程下载完后,立刻回调到主线程(即告诉主线程,图片已经下载完成)。然后主线程就可以对图片进行一系列相关操作。
有这样一个例子:
一个公司很大,有很多任务,其中销售任务交给销售部来完成销售,可是并不知道销售部什么时候卖完,但是公司也不会停下来什么事不做,就一直等着销售部卖完,这是不可能的,公司分配任务后,会接着做其他事情,当销售部卖完后,会向“定时器中断”一样向公司报告,我已完成销售,此时公司就会停下来,处理销售部完成销售,给销售部提成%10的操作。完成后再去完成刚刚停下来得工作。
分析:公司只是有一个方法,通知销售部来卖货。公司不确定销售部什么时候卖完,可是销售部知道,于是销售部制定了一个协议,规范了接口。然后公司遵从这个协议,实现协议中的方法。此时销售部是委托方,公司是代理方。
#import <Foundation/Foundation.h>
#import "SaleDetegate.h"
#import "Sale.h"
@interface Company :NSObject<SaleDetegate>
{
Sale *sale;
}
-(void)saleProduce;
-(void)doThing:(float)totalPrice;
@end
#import "Company.h"
@implementation Company
-(id)init
{
if(self=[superinit])
{
sale=[[Salealloc] init];
sale.delegate=self;//建立代理,委托方--》代理方,此时销售部是委托方,公司是代理方。
}
return self;
}
-(void)saleProduce
{
[salesaleProduce]; //通知销售部卖货
}
-(void) saleFinish:(float)totalPrice //实现销售部制定的协议方法,当销售部卖完时,回调
{
[selfdoThing:totalPrice];
}
-(void)doThing:(float)totalPrice
{
NSLog(@"总金额为%.2f,奖励销售部%.2f",totalPrice,totalPrice*0.9);
}
-(void)dealloc
{
[salerelease];
[superdealloc];
}
@end
#import <Foundation/Foundation.h>
#import "SaleDetegate.h"
@interface Sale : NSObject
@property (assign)NSUInteger produceNum;
@property (assign)float totalPrice;
@property (assign)id<SaleDetegate> delegate;
-(void) saleProduce;
@end
@implementation Sale
-(id)init
{
if(self=[superinit])
{
_produceNum=10;
_totalPrice=0;
}
return self;
}
-(void) saleProduce
{
while (self.produceNum) {
sleep(1);
self.produceNum--;
self.totalPrice+=10.0;
}
[self.delegatesaleFinish:self.totalPrice];//卖完货物,将值传递给公司,方向传值
}
@end
#import <Foundation/Foundation.h>
@protocol SaleDetegate <NSObject>
@required
-(void) saleFinish:(float)totalPrice;
@end
main.m
#import <Foundation/Foundation.h>
#import "Company.h"
#import "Sale.h"
int main(int argc,const char * argv[])
{
@autoreleasepool {
//OC中回调的概念和嵌入式中的“定时器和中断”是一样的作用
Company *company=[[Companyalloc] init];
[companysaleProduce];
[companyrelease];
}
return 0;
}