前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Objective-C 与 泛型

Objective-C 与 泛型

作者头像
酷酷的哀殿
发布2021-02-01 11:13:39
7940
发布2021-02-01 11:13:39
举报
文章被收录于专栏:酷酷的哀殿酷酷的哀殿

Objective-C 与 泛型

从 Xcode 7 开始,为了更简单和高效的与 Swift 交互, Objective-C 支持了引入了 3 个高级特性:轻量泛型Nullability annotationKindOf

本文希望对 轻量泛型 做一个简单的介绍。更多信息,请参考 llvm 或者 与 Objective-C API 交互[1]

轻量泛型 是什么?

轻量泛型 可以让开发者执行集合类的类型信息,并且支持与 Swift 的泛型系统进行相互转化。

为什么使用 轻量泛型?

通常情况下,我们使用下面的语法声明数组:

代码语言:javascript
复制
NSArray *dates;

通过在类型后面添加 <NSDate *>,我们可以告诉编译器:这个数组只接受 NSDate 类型的实例

代码语言:javascript
复制
NSArray<NSDate *> *dates;

下面,我们通过实例验证一下它的作用:

代码语言:javascript
复制
NSArray<NSDate *> *dates;
NSString *str = dates[2];

当我们编译上述代码时,clang 在语法校验时会自动提示 ⚠️ 信息:NSDateNSString 不兼容

image-20210105220623395

解决该 ⚠️ 的方案也很简单,把 NSString 换成 NSDate 即可。

代码语言:javascript
复制
NSDate *date = dates[2];

如何让自己的类支持 轻量泛型?

1、如下所示,声明类型时,开发者需要在 类名 后面新增一些typedef-names[2]

代码语言:javascript
复制
@interface NSCovariant1<T>
@interface NSCovariant1<T, U : NSObject *>

2、在实例方法或者类方法中,使用 T 代替普通的类型声明

代码语言:javascript
复制
- (void)setObject:(U)obj forKeyedSubscript:(T)key;

验证

下面,我们写一个完整的 Demo 对上面的功能进行验证:

代码语言:javascript
复制
// main.m

@import Foundation;

@interface KKMutableDictionary<KeyType, ObjectType> : NSObject

- (void)setObject:(nullable ObjectType)obj forKeyedSubscript:(KeyType <NSCopying>)key;

@end

@implementation KKMutableDictionary

- (void)setObject:(nullable id)obj forKeyedSubscript:(id <NSCopying>)key {

}

@end

int main() {
    KKMutableDictionary<NSString *, NSDate *> *dic = [KKMutableDictionary new];
    dic[@"today"] = @"2021-01-01";
    dic[@"today"] = [NSDate date];
    dic[@"today"] = nil;
    NSLog(@"%@", dic);
}

进行语法检测并打印语法树:

代码语言:javascript
复制
xcrun clang -fmodules -fsyntax-only -Xclang -ast-dump main.m

1、语法检测会提示 dic[@"today"] = @"2021-01-01"; 存在类型兼容问题

image-20210105223501712

2、源码的第 5 行的语法树如下:

image-20210105223959567

我们简单对上面的语法树进行讲解:

  • ObjCInterfaceDecl 代表类的声明,本例中是 KKMutableDictionary
  • 随后,是父类 NSObject
  • 最后是两个 ObjCTypeParamDecl : KeyTypeObjectTYpe

总结

本文分享了轻量泛型的用法,并通过 clang 命令将对应的语法树进行了介绍。

参考资料

[1]

与 Objective-C API 交互: https://github.com/949478479/Using-Swift-with-Cocoa-and-Objective-C-in-Chinese/blob/master/02-Interoperability/01-Interacting%20with%20Objective-C%20APIs.md#lightweight_generics

[2]

typedef-names: https://clang.llvm.org/doxygen/DeclObjC_8h_source.html#l00567

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 酷酷的哀殿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Objective-C 与 泛型
    • 轻量泛型 是什么?
      • 为什么使用 轻量泛型?
        • 如何让自己的类支持 轻量泛型?
          • 验证
        • 总结
          • 参考资料
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档