• 代理与协议


    在Objective C中,目前对象之间的通信方式主要是通过协议(Protocol)和块(blcokblock)。

    这次,先和大家分享如何通过协议实现对象之间的信息传递。

    首先简单描述一下协议是什么。

    协议是多个类共享的一个方法列表。协议中列出的方法没有相应的实现,需要由继承此协议的类来实现(所以定义协议的只有一个.h文件)。

    了解C#和Java的同学一看可能马上就想到了接口,其实在Objective C中,协议的概念和接口的概念是类似的,基本上可以类比过来。

    协议在.h文件中的定义看起来像下面这个样子,

    @protocol protocolName

    @optional

    method1

    ......

    @required

    method2

    ......

    @end

    首先简单解释一下@optional和@required关键字。当你使用了@optional关键字,那么下面声明的方法(例如,method1)都是继承此协议的类可选的实现的方法。也就是说,继承此协议的类既可以实现此方法也可以不实现此方法。那么如果使用@required关键字,则下面声明的方法(例如,method2)必须有继承此协议的类实现。当然了,这两个关键字你都可以不写,那么此时默认的方法就是可选择实现的方法,即继承此协议的方法既可以实现也可以不实现。

    上面是对协议的简单描述,那么具体如何在Objective C中使用协议进行消息传递呢?下面给出了一个简陋的例子,意在说明简单的实现流程。

    在这个例子中,涉及到两个类(Person类和Dog类)和一个协议(MyProtocol协议)。下面给出简单的实现。

    • MyProtocol协议

    1
    2
    3
    4
    #import <Foundation/Foundation.h>
    @protocol MyProtocol<NSObject>
    -(void)Bark;
    @end
    • Dog类接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #import <Foundation/Foundation.h>
    #import "MyProtocol.h"
                 
    @interfaceDog:NSObject{  
    id<MyProtocol> deleget;     //声明代理协议
    }
    -(void)SomthingHappen; 
    -(void)SetHost:(id)host;    //设置狗的主人
    @end
    • Dog类实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #import "Dog.h"
               
    @implementation Dog
    -(void)SomthingHappen{
       [deleget Bark];      //代理协议调用Bark方法
    }
    -(void)SetHost:(id)host{
       deleget = host; 
    }
    @end
    • Person类接口

    1
    2
    3
    4
    5
    #import <Foundation/Foundation.h>
    #import "MyProtocol.h"                 //此处引入MyProtocol协议
             
    @interface Person:NSObject<MyProtocol> //继承MyProtocol协议
    @end
    • Person类实现

    1
    2
    3
    4
    5
    6
    7
    #import "Person.h"
            
    @implementation Person
    -(void)Bark{               //此处实现MyProtocol协议中Bark方法
     NSLog(@"my dog is barking..");//当Dog对象调用SomthingHappen方法
    }                              //时会回调此处的Bark方法
    @end
    • Main方法调用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #import <Foundation/Foundation.h>
    #import "Person.h"
    #import "Dog.h"
    #import "MyProtocol.h"
         
    int main(int argc,const char *argv[])
    {
       @autoreleasepool{
          Person *p = [[Person alloc]init];
          Dog *dog = [[Dog alloc]init];
          [dog SetHost:p];     //设置代理对象为Person
          [dog SomthingHappen];//此方法可以回调Person中实现的Bark方法
      }
      return 0;
    }

    上述代码很简单,也只是简单的示意一下,协议(Protocol)的更多细节可以看这里。另外需要说明一下,上述代码实例是在ARC模式下实现的,所以没有考虑资源的释放,下次分享block概念的时候会在非ARC模式下演示,因为block的概念虽然像是方法,但是也需要进行资源释放,这一点很特别,虽然是小问题,但是却很重要。

  • 相关阅读:
    Travis CI Could not find or load main class org.gradle.wrapper.GradleWrapperMain 错误
    HyperSQL 链接参数中文件的路径
    Maven 在 pom.xml 文件中配置 repositories 仓库
    Flyway Validate failed: Migration checksum mismatch for migration version 1.0.0.01 错误
    Angular 服务
    Angular 主从组件
    Angular 显示英雄列表
    Angular 英雄示例教程
    L2-002. 链表去重---模拟
    HDU2057
  • 原文地址:https://www.cnblogs.com/luoxs/p/2690237.html
Copyright © 2020-2023  润新知