zoukankan      html  css  js  c++  java
  • ios 协议分析

    1 基本用途

    • 可以用来声明一大堆方法(不能声明成员变量)
    • 只要某个类遵守了这个协议,就相当于拥有了这个协议中的所有方法声明
    • 只要父类遵守了某个协议,就相当于子类也遵守了

    2 格式

    • 协议的编写
    @protocol 协议名称 <NSObject>
     // 方法声明列表....
    @end

    3 关键字

    协议中有2个关键字可以控制方法是否要实现(默认是 @required ),在大多数情况下,用途在于程序员之间的交流。

    • @required (默认): 这个方法必须要实现(若不实现,编译器会发出警告)
    • @optional : 这个方法不一定要实现

    4 协议遵守协议

    • 一个协议可以遵守其他多个协议, 多个协议之间用逗号 , 隔开
    • 一个协议遵守了其他协议,就相当于拥有了其他协议中的方法声明
    @interface 类名 : 父类名 <协议名称1, 协议名称2>
    
    @end

    5 基协议

    • NSObject 是一个基类,最根本最基本的类,任何其他类最终都要继承它
    • 其实还有一个协议,名字也叫 NSObject ,它是一个基协议,最根本最基本的协议
    • NSObject 协议中声明很多最基本的方法,比如 description, retain, release 等
    • 建议每个新的协议都要遵守 NSObject 协议

      当一个对象无法直接获取到另一个对象的指针,又希望对那个变量进行一些操作时,可以使用代理模式。 

      协议和代理是模块化开发和封装的产物。
      先讲一个小故事帮助大家理解:

      老王有一家餐馆,刚刚开始的时候规模很小,所以老王一个人做了所有的事情:扫地,做菜,迎宾,上菜,收银。但是后面随着规模的扩大,老王一个人就吃不消了,忙死也忙不过来了。这时候怎么办?大家都很清楚吧,招人呗!所以后面就有了服务员,收银员,大厨,保洁员。
    这就意味着原先老王的工作按模块进行了拆分。

      餐馆的工作流程(业务逻辑)简单来说是这样的:点餐->做菜->上菜->收银->打扫卫生。

      转换成编程世界的模型就是这样的:业务不是很复杂的时候,我们把所有的功能都写在一个类里面,这个类暂且叫老王,理论上所有的事情和功能都可以写到这个类里面。做菜方法,上菜方法,打扫方法......就造成了老王这个类非常的庞大和臃肿,并且容易出错。

      那我们开始招人了,新建了大厨类,服务员类,收银类,保洁类,这四个类。大厨类有做菜方法,服务员类点菜,上菜方法,收银类有收银方法,保洁类有打扫方法。

      仅仅这样还是不行的,因为模块开发必然就有模块分化以后模块之间的通信问题。大厨类只做菜 但是菜做好了怎么办,必须及时的上菜,让顾客享用。但是大厨自己不能上菜,所以大厨必须抛出菜做好了的信号,具体这个菜上不上,怎么上,就不是大厨关心的了。

      老王交代大厨,你只管做菜,菜做好了以后喊一声菜做好了(我见过一个餐馆是拉铃铛)。
      那么老王跟大厨定的这个规矩就是协议(protocol),下面看代码:

    DaChu.h
    
    /**
     *  下面是声明协议的固定格式,DaChuDelegate是协议的名称,因为是代理协议,名称格式为:类名+Delegate
     */
    @protocol DaChuDelegate <NSObject>
    - (void)doSomethingAftercaiZuohaole;
    @end
    
    @interface DaChu : NSObject
    /**
     *  delegate 是dachu类的一个属性,weak 关键字是为了避免循环引用,<DaChuDelegate>表示遵守DaChuDelegate协议
     *  更加直白点:在大厨心里有一个人接受他的菜好了的信号去做一些事情,具体这个人是谁,大厨不关心,这个人的代号是delegate
     */
    @property (nonatomic, weak) id <DaChuDelegate> delegate;
    - (void)kaiShiZuoCai;
    @end
    Dachu.m
    #import "DaChu.h"
    
    @implementation DaChu
    - (void)kaiShiZuoCai{
        NSLog(@"开始做菜");
        sleep(2);
        NSLog(@"做好菜了,该上菜了");
        
       //下面这句是判断 一下delegate是否实现了doSomethingAftercaiZuohaole方法,如果delegate没有实现
        //直接[self.delegate doSomethingAftercaiZuohaole];会crash
        if ([self.delegate respondsToSelector:@selector(doSomethingAftercaiZuohaole)]) {
            [self.delegate doSomethingAftercaiZuohaole];
        }
        
    }
    @end

    下面看一看laowang这个类里面的内容

    #import "LaoWang.h"
    #import "DaChu.h"
    
    @interface LaoWang ()<DaChuDelegate>//<DaChuDelegate>表示遵守DaChuDelegate协议,并且实现协议里面的方法
    
    @end
    
    @implementation LaoWang
    - (void)laoWangKaiYe{
        NSLog(@"老王开业了");
        
        DaChu *dachu1 = [[DaChu alloc] init];
        dachu1.delegate = self;//说明老王充当代理的角色,负责接收菜好了的信号。
        [dachu1 kaiShiZuoCai];//大厨开始做菜
    }
    - (void)doSomethingAftercaiZuohaole{
        NSLog(@"老王知道了");//这里可以通知服务员去上菜了
    }
    @end

    自定义代理模式分为6步,遵循这6步,就能把代理完整的实现。

    1、定义协议;

    2、定义代理属性;

    3、委托方通知代理来执行任务;

    4、代理类要服从协议;

    5、指定代理对象;

    6、代理类实现协议中的方法。

    protocol的继承

    protocol和类一样,同样可以进行继承,这个也是我遗漏的一点。

    @protocol Test1Delegate
    @end
    
    @protocol Test2Delegate <Test1Delegate>
    @end;

      这个时候,如果类实现了Test2Delegate这个协议,那么也必须实现Test1Delegate里面的方法。 我们自己写的protocol的时候,一般Xcode都默认帮我们继承了NSObject这个协议。如果你不继承的话也没啥大的影响,因为我们的对象都是继承自NSObject,而NSObject也实现了NSObject这个协议。所以,当我们需要调用NSObject协议里面的方法的时候,也不会出错。不过苹果还是推荐继承NSObject这个协议。

    protocol隐藏类的类型

      在我们iOS开发中也会出现这种形式,比如iOS7的导航栏动画,苹果只是需要你返回一个实现了UIViewControllerAnimatedTransitioning这个协议的对象就行了。

    还有一个可能在和第三方sdk打交道的时候见得比较多。在别人实现的框架里面,有的时候,不希望把类的类型和里面方法暴露给你,而你也不太可能直接创建这个对象。这个时候就可以采用protocol这个方式,让调用者无需知道类的类型,一样可以完成自己想要的操作。

    id <Test1Delegate>obj = [XXXX  createObj];

    调用者只需要通过[XXXX createObj]这个方法,获取一个实现Test1Delegate而不知道类型的实例。在需要的地方,这个obj可以直接调用协议里面的方法,因为,这个对象都已经实现了。



    
    
  • 相关阅读:
    100个精彩的开源游戏
    poj 2104 K-th Number
    Redis源代码分析-内存数据结构intset
    android音乐播放器开发 SweetMusicPlayer 实现思路
    MySQL 二进制日志(Binary Log)
    Node.js 博客实例(六)留言功能
    HBase总结(十二)Java API 与HBase交互实例
    window+Apache 配置虚拟主机(2)
    Web Service那点事
    JSP基本语法
  • 原文地址:https://www.cnblogs.com/fengmin/p/6139052.html
Copyright © 2011-2022 走看看