协议、代理、回调

来源:互联网 发布:域名纠纷 管辖 编辑:程序博客网 时间:2024/06/05 08:52

协议:

OC中的协议,类似于JAVA中的接口,用来规范接口。协议可以被多重继承(和JAVA中的接口完全相类似),oc和java和c++中一样不能多重继承,所以如果要实现多重继承,那么就可以用协议。

   

//协议中声明的方法,有两种权限

@required:(缺省)必须的,即遵从协议的类,必须实现这个方法

@optional:可选的,遵从协议的类,如果实现了这个方法,必须出卖,如果没实现也没关系。


创建一个MyProtocal的协议

//声明一个协议

@protocol MyProtocal <NSObject>

//

-(void)bark;


@end


Dog类遵从这个协议

#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,constchar * argv[])

{


    @autoreleasepool {

        

       Dog *dog=[Dognew];

        

        id<MyProtocal> obj=nil;//这是遵从协议MyprotocalID指针,只能指向遵从同样协议的对象

        

        obj=dog;//代理对象,遵从协议的对象不需要用强引用指向

        

        //指针只能接受协议上声明过得消息,不能接受协议上没有声明果的消息。

        

        

       //例如:

        [objbark];//可行

        

       // [obj shakeTail];//不可行,因为该方法在协议中没有声明,当然并不会直接报错,因为obj就是Dog对象指针,但是这样的写法是不符合OC的语法的。所以尽量不要使用。

        [dogrelease];

        

    }

   return0;

}



协议的重要用处,一个是规范接口,一个是实现代理


代理:

代理是完成两个对象间通信的一种机制。一个对象发送数据给另一个对象。

代理多用于传值通信:正向传值和反向传值。

【注】代理是实现两个类的对象间通信的一种机制。

【委托方】主动方 持有带协议的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


main.m

#import <Foundation/Foundation.h>

#import "Bordcast.h"

#import "Radio.h"

int main(int argc,constchar * argv[])

{


    @autoreleasepool {

       Bordcast *bordcast=[[Bordcastalloc]init];



       Radio *radio4=[[Radioalloc]init];

        radio4.ID=@"radio4";

       //建立代理对象

        bordcast.delegte=radio4;

        

        [bordcaststartBordcast:@"hello world"];

        

        

        [bordcastrelease];


        [radio4release];

    }

   return0;

}


//反向传值
反向传值也叫回调,这个和C++中的函数回调原理相同。


回调,类似于嵌入式中的“定时器和中断”,即某个主方法在运行中,将一个任务交给另一个方法完成,但是主方法并不知道这个方法什么时候完成,所以当这个方法完成后,应该自动的告诉主方法已经完成这个任务了。在项目实际开发中,用到的地方,有一个主线程,开启一个副线程去下载图片,主线程接着做自己的事,直到副线程下载完后,立刻回调到主线程(即告诉主线程,图片已经下载完成)。然后主线程就可以对图片进行一系列相关操作。


有这样一个例子:


一个公司很大,有很多任务,其中销售任务交给销售部来完成销售,可是并不知道销售部什么时候卖完,但是公司也不会停下来什么事不做,就一直等着销售部卖完,这是不可能的,公司分配任务后,会接着做其他事情,当销售部卖完后,会向“定时器中断”一样向公司报告,我已完成销售,此时公司就会停下来,处理销售部完成销售,给销售部提成%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,constchar * argv[])

{


    @autoreleasepool {

        

        //OC中回调的概念和嵌入式中的定时器和中断是一样的作用

        

       Company *company=[[Companyalloc]init];

        [companysaleProduce];

        [companyrelease];

    }

   return0;

}





0 0