zoukankan      html  css  js  c++  java
  • Objective

    学到现在, 我们很快就要结束OC的教程了, 讲完protocol, OC语法就全部学完了, 现在我们来看看什么protocol, 在OC中, 我们都知道要.h文件里是用来声明方法和成员变量, .m文件里是用来实现的, 也知道类别是给系统类扩充一些必要的方法, 那么有没有一种机制是用来给我们自定义的类声明方法的呢? 其实是有的, 那就是protocol, 也就是协议, 下面让我们一起来看看:


    例子:

    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    
    - (void)test;
    
    @end
    
    @implementation Person
    
    - (void)test
    {
        NSLog(@"我是test方法.");
    }
    @end

    这个就是我们以前所运用的方法声明, 但这样子的声明方式就只能在一个类里面使用, 如果另一个类也要使用, 就必须拷贝一份过来, 重新声明, 重新实现, 但protocol出现之后, 这样子的问题就不存在了, 下面让我们来继续看看:



    #import <Foundation/Foundation.h>
    
    @protocol MyProtocol
    
    - (void)test;
    
    @end
    

    #import <Foundation/Foundation.h>
    #import "MyProtocol.h"
    
    @interface Person : NSObject <MyProtocol>
    
    @end
    
    @implementation Person
    
    - (void)test
    {
        NSLog(@"我是test方法.");
    }
    
    @end

    在这之前, 我们都知道冒号" : "是用在继承, 那么尖括号" <> "就是用在协议, 只要声明一个协议, 无论多少个类要用, 也不需要拷贝, 直接遵守这个协议, 那么就可以拥有协议里所有的方法.

    PS: 父类遵守了协议, 子类一样也可以使用, 原理和继承类似.



    那么protocol里有什么需要注意的呢?

    例子:



    为什么在Person.m文件里面会出现警告呢? 其实这个和Protocol的机制有关, 在Protocol中有两种方法声明, 一种是@required, 另一种是@optional, 直接翻译我们也知道第一个是必须的, 第二个是可选的, 而在Protocol声明的方法里, 默认就是required, 也就是必须实现的, 一旦遵守了协议的类, 没有实现必须的方法时, 那么编译器就会报警告.



    那么问题来了, 既然默认都是required, 那么干嘛还要写这个?? 不是蛋疼没事做么? 其实是有一定的道理的, 这个写出来并不是给编译器看的, 是用来给我们程序员之间交流的, 当你的合作伙伴看到了这个之后, 他就知道, 原来这个方法一定要我去实现, 那么他就会去实现这个方法, 你不写的的话, 那他就会跑过来问你, 这个我需不需要实现啊, 哪个是可选的啊, 等等一系列额问题~~大家都懂的~~





    我们都知道OC是单继承的, 不可以继承多个类, 那么协议呢? 其实协议是可以多个遵守的, 比如:





    其实协议一般是使用在设计模式场景, 比如代理模式, 观察者模式等等, 这个我们后面会慢慢讲~~





    其实协议还有一种, 叫做基协议, 在我们之前学习过一个东西叫做基类NSObject, 就是所有类都继承于它, 所以叫做基类, 而在协议中也有一个基协议, 它的名字也叫做NSObject, 而所有的协议也必须遵守它, 比如:





    既然有基协议这个原理, 那么我们是不是可以猜想一下, 一个自定义的协议是否可以遵守另一个自定义的协议呢? 其实是可以的, 比如:




    MyProtocol2遵守了MyProtocol协议, 而Person又遵守了MyProtocol2协议, 那么在Person里就不用遵守它了, 直接遵守MyProtocol2就可以拿到MyProtocol的方法, 并且实现, 和子父类继承关系有些相似.

    PS: 因为MyProtocol遵守了基协议, 而MyProtocol2又遵守了MyProtocol, 所以MyProtocol2就不需要遵守基协议.



    在某些情况, 我想让系统类遵守我自定义的协议怎么办? 比如:



    我想让obj这个对象遵守我自定义的协议, 但是NSObject这个类是不可能遵守我自定义的协议的, 那么如何解决?? 其实很简单, 继续往下看:



    解决办法就像上面的obj2obj3一样, 但obj3出现一个问题, 因为NSObject这个基类是不可能遵守我们自定义的协议的, 所以会报警告, 说类型不匹配, 而obj2使用的是Person, 所以类型匹配成功, 只显示了该对象并没有使用, 和obj一样.



    使用Protocol是有一个书写规范的, 这个规范和声明类是一样的, 下面我们来看看:


    Person.h文件中只用@protocol声明有该协议, 直到真正要去使用的时候才在.m文件里面引用, 这可以保证我们app的性能.




    对了, 其实属性也可以遵守协议的, 比如:





    总结:

     1.协议的定义

     @protocol 协议名称 <NSObject>

      // 方法声明列表....

     @end


     2.如何遵守协议

     1> 类遵守协议

     @interface 类名 : 父类名 <协议名称1, 协议名称2>

     @end

     

     2> 协议遵守协议

     @protocol 协议名称 <其他协议名称1, 其他协议名称2> 

     @end

     

     3.协议中方法声明的关键字

     1> @required (默认)

       要求实现,如果没有实现,会发出警告

     

     2> @optional

       不要求实现,怎样不会有警告

     

     4.定义一个变量的时候,限制这个变量保存的对象遵守某个协议

     类名<协议名称> *变量名;

     id<协议名称> 变量名;

     例子:

     NSObject<MyProtocol> *obj;

     id<MyProtocol> obj2;

     

     如果没有遵守对应的协议,编译器会警告

     

     5.@property中声明的属性也可用做一个遵守协议的限制

     @property (nonatomic, strong) 类名<协议名称> *属性名;

     @property (nonatomic, strong) id<协议名称> 属性名;

     例子:

     @property (nonatomic, strong) Dog<MyProtocol> *dog;

     @property (nonatomic, strong) id<MyProtocol> dog2;




    再补充一点:

     1.协议可用定义在单独.h文件中,也可用定义在某个类中

     1> 如果这个协议只用在某个类中,应该把协议定义在该类中

     2> 如果这个协议用在很多类中,就应该定义在单独文件中

     

     2.分类可用定义在单独.h.m文件中,也可用定义在原来类中

     1> 一般情况下,都是定义在单独文件

     2> 定义在原来类中的分类,只要求能看懂语法




    好了, OC语法到此告一段落了, 谢谢大家的观看~~

  • 相关阅读:
    vue 父子组件通信props/emit
    mvvm
    Ajax
    闭包
    【CSS3】---only-child选择器+only-of-type选择器
    【CSS3】---last-of-type选择器+nth-last-of-type(n)选择器
    【CSS3】---first-of-type选择器+nth-of-type(n)选择器
    【CSS3】---结构性伪类选择器—nth-child(n)+nth-last-child(n)
    【CSS3】---结构性伪类选择器-first-child+last-child
    vue路由切换和用location切换url的区别
  • 原文地址:https://www.cnblogs.com/iOSCain/p/4282816.html
Copyright © 2011-2022 走看看