oc 的 协变性与逆变性

?协变性与逆变性是类型关系在范畴论的定义。是类型的继承关系在高阶类型中的定义?

__kindof只是在统一继承体系下方便了类型转化,提供了使用时语法上的便捷;但是对于类型转换是否正确不做判定;

kindDerived *derived = [self getInstance];

- (__kindof kindBase *) getInstance{

    return [kindDerivedX new];

}

2.4 协变性与逆变性

  • 因为有了泛型集合的概念,相比之前,我们的类型实际上更加复杂了,比如还拿我们自定义的集合类型来举例,array 和 muArray 在编译器看来已经是不同的类型,如果我们强行转换,会报如下的警告:


    OcNew6

  • 因此,就有了逆变和协变这个概念,不指定泛型类型的对象可以和任意泛型类型转化,但指定了泛型类型后,两个不同类型间是不可以强转的,假如你希望主动控制转化关系,就需要使用泛型的协变性和逆变性修饰符。

  • 上面的情况,我们将自定义的类做如下修改,就不会出现警告:

  • NSMutableString 是 NSString 的子类,在 MyArray 定义中加入了 __covariant 可以进行转换。但将 MyArray<NSString *> 转换为 MyArray<NSMutableString *> 时仍会报警告。

    OcNew7

3、类型延拓符

  • 在开发中,开发者经常会遇到这样的情况,例如通过 tag 获取某些 UI 控件时,viewWithTag 方法通常会返回给我们一个 UIView 类型的指针,这就需要开发者手动的强转一下,十分麻烦。新增加的 __kindof 修饰符可以帮助我们解除这个烦恼。

    • 创建一个自定义的数组对象,并向其中添加一个 UIButton,我们会看到有如下一个警告:

      OcNew8

    • 这也是我们开发中常遇到的问题,以前需要强转。但是以后就不需要了,我们在声明这个数组时加上一个 __kindof 修饰符。警告就消失了,这个修饰符就是告诉编译器,这里可以返回 UIView 的子类指针。

  • id,instancetype,__kindof 作为返回值时的比较:

    id:
        优点:可以调用任何对象方法。
        缺点:不能使用点语法,不能做编译检查。

        Xcode5 之前,返回 id。

    instancetype:
        优点:会自动识别当前类的对象.

        Xcode5 instancetype。

    __kindof:
        优点:调用方法时,通过返回值提示,可以看到具体的返回类型,如:Person *,而前两者不会看到。

        xcode7 __kindof:表示当前类或者子类。

http://www.cnblogs.com/QianChia/p/5782925.html#_label1

原文地址:https://www.cnblogs.com/feng9exe/p/10523777.html