zoukankan      html  css  js  c++  java
  • OC基础回想(十二)协议

    在OC基础(十一)中我们讨论了类别和非正式协议的奇异之处。在使用非正式协议时。能够仅仅实现你想要获得响应的方法。也不必在对象中声明不论什么内容来表示该对象可用作托付对象。

    全部这些任务能够用最少的代码完毕。

    以下来学习正式协议。

    1. 正式协议

         与非正式协议一样。正式协议包括了方法和属性的有名称列表。

    但与非正式协议不同的是,正式协议须要显示地採用。採用(adopt)协议的办法是在类的@interface声明中列出协议的名称。採用协议后,你的类就要遵守该协议。採用协议就意味着你承诺实现该协议的全部方法。否则,编译器会生成警告来提醒你。

    1.1 声明协议

    声明一个协议的方法很easy:
    @protocol myProtocol <NSObject>
     @required
    -(void)protocolMethodA:(NSString *)string;
    @optional
    -(void)protocolMethodB:(NSString *)string;
    @end

    说明:
    (1)第一行是声明这个协议的名字为myProtocol。尖括号里的NSObject本身也是一个协议,当中定义了非常多主要的协议函数。比方performSelector。isKindOfClass,respondsToSelector,conformsToProtocol,retain,release等。
    (2)协议接口分为required和optional两类。required顾名思义是说遵守这个协议的那个类“必需要”实现的接口,而optional则是能够实现也能够不实现的。协议接口的定义和普通的函数定义是一样的。

    (3)最后一行@end表示协议定义结束。这个协议的定义一般是在.h文件里。


    1.2 定义一个类遵循这个协议

    @interface myClass <myProtocol>
    @intrerface myClass : NSObject <myProtocol>
    @interface myClass : NSObject <myProtocol, NSCoding>
    说明:
    上面各自是三种不同的情况。编译的时候编译器会自己主动检查myClass是否实现了myProtocol中的必要的(@required)接口。假设没有实现则会发出一个警告信息。另外须要注意的是,假设有继承自myClass的子类,这些子类也是会自己主动遵循myClass所遵循的协议的。并且也能够重载这些接口。


    2.为什么要使用正式协议

    苹果的官方文档指出三个原因:

    • To declare methods that others are expected to implement
    • To declare the interface to an object while concealing its class
    • To capture similarities among classes that are not hierarchically related

    事实上还有第四个非常重要的原因,那就是降低继承类的复杂性。一个经典的样例就是iOS UI框架里面的UITableViewController类。假如没有“协议”功能。用户就必须选择用继承和重载接口的方法来实现复杂的UI控制以及其它事件的处理——这就对基类的设计提出了更大的挑战了。对于像这样一个table view,一个非常好的实现方法就是採用协议,由协议里的接口来控制不同的数据源以及各种复杂的用户操作。

    UIKit中设计了两个非常好的协议UITableViewDelegate,UITableViewDataSource来实现UITableViewController的控制。

    不论什么遵循这两个协议的类都能够实现对UITableView的控制。


    3.关于id类型的运用

         id 类型在iOS中是一个通用类型,有点类似C语言的void*类型。编译器不能检查到定义为id类型的变量的实际类型,id类型的识别是发生在执行时阶段。可是我们能够用 id<protocol_name> obj;这种语法形式在编译阶段就能够让编译器知道obj仅仅能够发送protocol_name中的消息,假设所发送的消息不在protocol_name中,编译器会给一个警告信息“Instance method 'xxxx:' not found......”。

    这样的情况多用于代理模式的实现。比方某一个类有一个delegate 的property:

    id <myProtocol> delegate;
         这样。在编译阶段我们就能够知道用delegate所发送的消息是不是在它所遵循的myProtocol中的消息。好了。 到这里笔者钻起了牛角尖,我把id后面的 <myProtocol>删掉。然后用delegate发送一个并不存在于myProtocol中的消息。结果编译器还是给了“Instance method 'xxxx:' not found......”的警告信息。

    更奇怪的是,当发送一个存在于myProtocol中的消息时,编译器居然没有这种警告信息。这两个測试并不能说明之前的解释是错误的,姑且觉得id<myProtocol> delegate这种写法是为了便于知道这个delegate遵循了myProtocol的协议吧

  • 相关阅读:
    38861cba61c66739c1452c3a71e39852.ttf net::ERR_ABORTED 404 (Not Found)
    php 进制转换base_convert
    mysql find_in_set 函数 使用方法
    xmind 破解
    python 获取 一个正整数的二进制
    算法 求一个数的平方根
    详细的描述一个测试活动完整的过程。
    常见的测试用例设计方法都有哪些?请分别以具体的例子来说明这些方法在测试用例设计工作中的应用。
    HTTP 协议中 Vary 的一些研究
    svn cleanup failed–previous operation has not finished; run cleanup if it was interrupted
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/7119905.html
Copyright © 2011-2022 走看看