协议和代理

本文介绍了Objective-C中的协议和代理模式。协议定义了一组方法,指定类需实现这些方法,支持委托对象实现自定义行为。代理模式允许两个对象协同工作,减少耦合度并简化对象行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.协议

Objective-C中的协议(Protocol)类似于常用的接口,协议(Protocols)中定义的方法,在类中实现。协议(Protocol)通常用来实现委托对象(Delegate Object)。委托对象(Delegate Object)一般用来自己定义行为或者动作,也就是调用自己定义方法,但自己不实现该方法,委托其它的类来实现该方法。

协议列出了一组方法,这些方方法有些是选择实现的,有些是必须实现的。

协议定义的格式:

HelloProtocol.h

#import <Foundation/Foundation.h>    

@protocol HelloProtocol   <NSObject>

- (void) requiredMethod;    

@optional  

- (void) optionalMethod1;  

- (void) optionalMethod2;  

@end

定义一项协议时,可以可以扩展现有的协议的定义。如@protocol HelloProtocol   <NSObject>说明HelloProtocol协议也采用了NSObject协议,因此任何采用HelloProtocol协议的类都必须实现此协议列出的方法,以及NSObject协议的方法。

@end之前的所有方法都是协议的一部分。@required是缺省值,是必须实现的方法,@optional是可以选择的。协议只有一个.h文件,本身不是类,他是定义了一个其他类可实现的接口。

协议的实现

Person.h

#import <Foundation/Foundation.h>

#import "HelloProtocol.h"  

@interface Person : NSObject <HelloProtocol>  

@end  

Person.m

#import "Person.h" 

@implementation Person

- (void)requiredMethod{

NSLog(@"这是一个必须实现的方法"); 

}

- (void)optionalMethod1{ 

NSLog(@"这是一个可选的方法1");

}

- (void)optionalMethod2{ 

NSLog(@"这是一个可选的方法2");

}

@end  

用协议修饰变量

1 定义变量:

       id<MyProtocolName>myNewVariable;     

       那么myNewVatiable是遵循我们定制的这个MyProtocolName协议的。这里存在一个编译器校验,所以向myNewVariable指派一个id变量不会产生这条信息,以为编译器不知道存储在id变量中的对象是否遵循MyProtocolName协议。

2 定义函数:

      - (void) doSomethingWithThisObject: (id<MyprotocolName>) aObject

      那么这个函数的参数是需要遵循我们定制的这个MyProtocolName协议的。

继承中的协议

如果父父类遵守一项协议,那么子类也会遵守这项协议。如果父类的实现文件中没有实现这个协议的方法,无论是否实现子类中的协议的方法,当父类对象调用协议中的此方法时,并不能够正常运行;当父类的实现文件实现了协议中的方法,而子类的实现文件没有实现协议中方法,当父类对象调用协议中的方法时,会调用父类实现文件中的方法,当子类对象调用协议中的函数时,也会调用父类实现文件中的方法;当父类的实现文件实现了协议中的方法,而子类的实现文件也实现协议中方法,当父类对象调用协议中的方法时,会调用父类实现文件中的方法,当子类对象调用协议中的函数时,也会调用子类实现文件中的方法。

可以使用ConformsToProtocal:方法检查一个对象是否遵守某项协议.

例如有一个名为currentObject的对象,并且想要查看它时候是遵循Drawing协议.可以向他放松绘图消息
 
这里使用一个专用的@protocol指令用于获取一个协议名称.并产生一个Protocol对象.
最后,分类也可以采用协议,例如:
@interace Fraction (Stuff) <NSCopying, NSCoding>
Fraction拥有一个分类Stuff,这个分类采用NSCopyingNSCoding协议。
和类名一样,协议名也必须是唯一。
2.代理
代理是指一个对象提供机会给另一个对象中的行为发生变化是做出的反应。基本思想是:两个对象协同解决问题,通常用于对象之间的通信。
代理设计模式的基本特点:

  • 简化了对象的行为,最小化了对象之间的耦合度。
  • 使用代理,一般来说无需子类化。
  • 简化了我们应用程序开发,既容易实现,有灵活
例如:
A.h
#import <Foundation/Foundation.h>
@class B;
@interface A:NSObject
{
B delegate;
}
-(id) init ;
-(void) FunToOther;
@end
A.m
@implementation A
-(id) init 
{
delegate = B;
}
-(void) FunToOther
{
[delegate Fun];
}
@end
委托对象的实现
B.h
#import"A.h" 
@interface B:NSObject<MyDelegate>  
@end  
B.m
@implementation B
-(void)fun  
{  
    //实现Mydelegate中制定的方法  
}  
@end  
这样的话A就可以委托B去做fun这件事情了。
      那么这个函数的参数是需要遵循我们定制的这个MyProtocolName协议的。
分类也可以采用协议,例如:
@interface Fraction (Stuff ) <NSCopying , NSCoding>
Fraction拥有一个分类Steff,这个分类遵守NSCopying ,和NSCoding协议。
和类名一样,协议名必须是唯一的。
2,代理
 代理是指一个对象提供机会给另一个对象中的行为发生变化是做出的反应。基本思想是:两个对象协同解决问题,通常用于对象之间的通信。
代理设计模式的基本特点:
  • 简化了对象的行为,最小化了对象之间的耦合度。
  • 使用代理,一般来说无需子类化。
  • 简化了我们应用程序开发,既容易实现,有灵活。
    下面来举一个经典的实例,妈妈和保姆的例子:妈妈把孩子委托给保姆照顾,于是将需要完成的事情写成一个协议:协议声明如下:
2.代理     
 代理是指一个对象提供机会给另一个对象中的行为发生变化是做出的反应。基本思想是:两个对象协同解决问题,通常用于对象之间的通信。
代理设计模式的基本特点:
  • 简化了对象的行为,最小化了对象之间的耦合度。
  • 使用代理,一般来说无需子类化。
  • 简化了我们应用程序开发,既容易实现,有灵活。
  • 例如:母亲与保姆的关系

 id currentObjec; 

([currentObjec ConformsToProtocal: @protoco (Drawing) : == YES]){ 

....//DO SOMETHING; 

}

也可以使用respondsToSelector:检查是否实现了可选的outline方法。例如:

if ([currentObjecrespondsToSelector:@selector(outline)] == YES)

[currentObjec outline];

#import "Person.h"  

@implementation Person  

- (void)requiredMethod{  

    NSLog(@"这是一个必须实现的方法");  

}  

- (void)optionalMethod1{  

    NSLog(@"这是一个可选的方法1");  

- (void)optionalMethod2{  

    NSLog(@"这是一个可选的方法2");  

} 

如果你采用采用多项协议,只需把它们都列在尖括号中,并且用逗号分开。

如果你定义了自己的协议,那么不必自己实现它,但是,这就告诉其他人,如果采用这个协议,则必须实现这些方法,这些方法可以从超类继承,这样,如果一个类遵守NSCopying协议,那么它的子类也遵守。当一个类遵守一个协议时,同时他也有一个子类,如果父类没有实现协议中的方法,无论子类是否实现协议中的方法,编译器都会发出警告,若子类实现了协议中的方法,当向子类对象发送这个消息时,可以正常运行;如果父类和子类各自实现了协议中的代码,当向他们的对象发送消息时,他们会调用各自的方法;如果父类实现协议中的方法,而子类没有实现这个方法,当向子类发送这个消息时,会调用父类所实现的方法。

可以使用conformsToProtocol:方法检查一个对象是否遵循某项协议。例如:

检查名为currentObject对象是否遵循HelloProtocol  协议,则可以:

id currentObject;

if ([currentObject conformsToProtocol: @protocol (HelloProtocol  ) ] )

{

给currentObject发送paint,erase和outline消息

}

这里使用@protocol 指令获取一个协议的名字,并产生一个HelloProtocol 的对象,并作为conformsToProtocol:方法的参数。

if( [currentObject  respondsToSelector:@seletor (optionalMethod1)])

{

[currentObjectoptionalMethod1];

}

 定义变量:

       id<MyProtocolName>myNewVariable;     

       那么myNewVatiable是遵循我们定制的这个MyProtocolName协议的。如果myNewVariable不遵守协议,则会发出一条警告。

        如果指派给myNewVariable的时id类型,那么编译器无法知道myNewVariable是否遵守这个MyProtocolName协议的。

如果这变量保存的对象遵守多个协议,则可以将多个协议放在尖括号中,用逗号分开。

 定义函数:

      - (void) doSomethingWithThisObject: (id<MyprotocolName>) aObject

  • #import <Foundation/Foundation.h>

    @protocol Job <NSObject>

    -(void)takeEat;

    -(void)takeSleep;

    -(void)takePlay;

    -(void)takeShower;

    @end

    我们再声明Nurse类 即代理的人:

     

    #import <Foundation/Foundation.h>

    #import "Job.h"

    @interface Nurse : NSObject<Job>//实现该协议

    @end

    实现文件:

     

    #import "Nurse.h"

    @implementation Nurse

    -(void)takeEat

    {

        NSLog(@"小孩饿了,喂它吃饭");

    }

    -(void)takeSleep

    {

        NSLog(@"小孩困了,哄他睡觉");

    }

    -(void)takePlay

    {

        NSLog(@"小孩醒来了,陪他玩");

    }

    -(void)takeShower

    {

        NSLog(@"晚上给小孩洗澡");

    }

    -(void)dealloc

    {

        NSLog(@"Nurse is dealloc");

    }

    @end

    再声明一个morther类:

    #import <Foundation/Foundation.h>

    #import "Job.h"

    @class Nurse;

    @interface Morther : NSObject

    {

        NSString *name;

        id<Job> delegate;   //此处声明一个代理人,从而mother可以让代理人完成需要代理的事情

    }

    -(id)initWithName:(NSString *)_name delagat:(id<Job>)_delagete;  //传入代理人

    @property(nonatomic,copy)NSString *name;

    -(void)delagateThings;// 被代理的事情

    @end

    //实现文件

     

    #import "Morther.h"

    #import "Nurse.h"

    @implementation Morther

    -(id)initWithName:(NSString *)_name delagat:(id)_delagete

    {

        self=[super init];

        if (self) {

            if (name!=_name) {

                [name release];

                name=[_name copy];

                [delegate release];

                delegate=[_delagete retain];

            }

        }

        return self;

    }

    @synthesize name;

    -(void)dealloc

    {

        [name release];

        [delegate release];

        NSLog(@"host is dealloc");

    }

    -(void)delagateThings

    {

        int i;

        switch (i) {

            case 1:

                [delegate takeEat];

                break;

            case 2:

                [delegate takePlay];

                break;

            case 3:

                [delegate takeShower];

                break;

            case 4:

                [delegate takeSleep];

                break;

            default:

                break;

        }

        i++;

    }

    @end




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值