美文网首页iOS技术
如何理解IOS中泛型

如何理解IOS中泛型

作者: lenka01 | 来源:发表于2021-01-20 23:21 被阅读0次

在平时开发过程中,几乎所有人都接触过泛型这个概念,苹果从IOS9以后引入了泛型这个概念,从系统库到我们自定义泛型中,或多或少都有一定的理解。所谓的泛型,即为了在使用某个对象时,提前申明好这里应该放什么类型的数据,避免使用者对数据类型的捉摸不清。 下面举几个例子分别说明,让大家影响更为的深刻。

1.泛型是什么

泛型是对集合中对象的一种抽象,俗话说:越抽象的功能越好用。从集合中取出对象时,不需要进行类型转换,可直接调用方法。

    NSArray<NSString *> *arrays;
    arrays.firstObject.length;

2.泛型语法

@interface 类名 < __covariant ObjectType : id >

我们以NSArray来举例分析:

@interface NSArray<__covariant ObjectType> : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>

@property (readonly) NSUInteger count;
- (ObjectType)objectAtIndex:(NSUInteger)index;
- (instancetype)init NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithObjects:(const ObjectType _Nonnull [_Nullable])objects count:(NSUInteger)cnt NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;

@end

可以指定泛型数据类型,默认为id(可以不写),作用域为@ interface到@end之间

3.集合类型中泛型应用

1.1 NSArray中的自定义泛型

比如说,创建了一个数组对象,只允许里面存放字符串类型的数据。那么我们该如何设计呢?这里典型的一个泛型思想。

@property (nonatomic,strong)NSMutableArray <__kindof NSString *>*list;

就是这么简单。我们再向其中添加几个number数据,看下会有什么情况发生?

[self.list addObject:@(1)];

经典的报错信息如下

image.png
大概意思,你明明定义了一个只会存放字符串的数组,却要往里面塞数字。所以,编译器就告诉了我们这是不允许的。所以,这就是泛型的一个好处了提前申明

1.2 NSArray官方定义泛型

查看NSArray源码,我们可以发现有几个奇怪的关键字不是很熟悉。

@interface NSArray<__covariant ObjectType> : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>

@property (readonly) NSUInteger count;
- (ObjectType)objectAtIndex:(NSUInteger)index;
- (instancetype)init NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithObjects:(const ObjectType _Nonnull [_Nullable])objects count:(NSUInteger)cnt NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
@end

我们可以看到有个关键字__covariant,它表示协变, 用于泛型数据强转类型,可以向上强转,子类可以转成父类。

4. 普通对象中的自定义泛型

当我们申明一个Person类型,也可以自定义泛型(替代id这种古老的写法)

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Person<ObjectType> : NSObject

@property (nonatomic, strong) ObjectType langguage;

@end

NS_ASSUME_NONNULL_END
    iOS *ios = [[iOS alloc] init];
    Java *java = [[Java alloc] init];
    
    Person <iOS *>*john = [[Person alloc] init];
    john.language = iOS;
    
    Person <Java *>*david = [[Person alloc] init];
    david.language = java;

其实这里的ObjectType类型就是上面说的泛型。这里我们把per1指向per。(没有添加协变)

- (void)test2 {
    IOS *iOS = [IOS new];
    JAVA *java = [JAVA new];

    Person<IOS *> *per = [Person new];
    per.langguage = iOS;

    Person<Language *> *per1 = [Person new];
    per1 = per;
}
image.png

为了解决上面那个编译器警告,我们可以添加协变关键字,来避免编译器警告.

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Person<__covariant ObjectType> : NSObject

@property (nonatomic, strong) ObjectType langguage;

@end

NS_ASSUME_NONNULL_END

协变允许子类转化为父类。系统默认都是这种行为。

同样的我们把代码稍微改一下,让per指向per1

 IOS *iOS = [IOS new];
    JAVA *java = [JAVA new];


    Person<IOS *> *per = [Person new];
    per.langguage = iOS;


    Person<Language *> *per1 = [Person new];
    per = per1;

结果报错如下:


image.png

对应的,还有个__contravariant,它表示逆变, 可用于泛型数据强转换,可以向下强转,允许父类可以转成子类

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Person<__contravariant ObjectType> : NSObject

@property (nonatomic, strong) ObjectType langguage;

@end

NS_ASSUME_NONNULL_END

这样就可以避免编译器错误。

相关文章

  • 如何理解IOS中泛型

    在平时开发过程中,几乎所有人都接触过泛型这个概念,苹果从IOS9以后引入了泛型这个概念,从系统库到我们自定义泛型中...

  • Java泛型

    本文介绍的知识点 泛型是什么? 泛型的使用在反射中使用泛型在集合类中使用泛型 关于泛型擦除如何理解?如何避免泛型擦...

  • iOS 强大的泛型

    iOS 强大的泛型 iOS 强大的泛型

  • JDK1.5后增加了泛型,那么为什么要有泛型呢?我们该如何自定义

    本篇主要讲解java泛型的理解、集合中简单使用泛型、自定义泛型结构(包括类、接口、方法)。 一、什么是泛型? 通俗...

  • 不理解Typescript泛型?看完就理解了

    如何理解泛型 泛型(Generic Type)存在于许多编程语言中,许多刚接触Typescript且没有Java、...

  • [Java菜鸟系列] 红警思维看"泛型"

    J005-[Java菜鸟系列] 红警思维看"泛型" 菜鸟:如何理解 “ArrayList” 中的 < E>?...

  • java 泛型

    1,如何实例化泛型 2,如何获取java中的泛型类型 调用(通常在构造方法中调用):

  • Typescript(十三)泛型

    泛型:[generic - 通用、泛指的意思],那最简单的理解,泛型就是泛指的类型。 一:函数中的泛型 1:定义一...

  • java 泛型解析

    Java 泛型 1、泛型的精髓是什么 2、泛型方法如何使用 概述: 泛型在java中具有重要地位,在面向对象编程模...

  • swift4 泛型(一)

    swift 泛型 OC 是没有泛型也不支持命命空间的,但是swift中这两者都有,本章主要介绍 泛型 对于iOS开...

网友评论

    本文标题:如何理解IOS中泛型

    本文链接:https://www.haomeiwen.com/subject/gpslzktx.html