Objective-C轻量级泛型
在Apple发布Xcode7的时候,不仅把Swift编程语言升级到了2.0版本,而且还对Objective-C做了许多提升,包括引入__nonnull/__nullable。其中,对于Objective-C编程语言本身而言,更为有用的便是轻量级泛型。
其中,比较明显的体现就是NSArray、NSDictionary这些容器类都采用了新引入的轻量级泛型。通过轻量级泛型,我们可以非常容易地获取其中的元素,并访问其相印特有的属性和方法。我们举一个简单例子来阐明轻量级线程带来的方便:
// 不带泛型的情况
NSArray *numArray = @[@, @, @];
int sum = [(NSNumber*)numArray[] intValue] + [(NSNumber*)numArray[] intValue] + [(NSNumber*)numArray[] intValue]; // 使用泛型的情况
NSArray<NSNumber*> *numArray = @[@, @, @];
int sum = [numArray[] intValue] + [numArray[] intValue] + [numArray[] intValue];
我们通过上述例子就能看到轻量级泛型带来的语法上的便利性,即它是一块甜美的语法糖(syntax sugar)。
之前Apple LLVM 6.0对C11标准的泛型——generic selection在Objective-C上支持得还不够良好,但Apple LLVM 7.0上已经能完美支持了。比如下述例子:
int flag = _Generic(@, NSNumber*:, NSString*:, int:, default:);
NSLog(@"The flag is: %d", flag);
上述代码将成功地输出“The flag is: 1”。
与C11的generic selection所不同的是,Objective-C自带的泛型其本质为covariant type,即协变类型。也就是,其泛型与Java的有些类似。它要求泛型必须是一个Objective-C类类型,即至少为id类型。对于上述NSArray的例子,我们在声明一个Objective-C对象引用时,通过在类名后面添加<NSNumber*>来指明当前NSArray里的元素都是NSNumber*类或其子类类型。这样,我们在访问其元素时可直接访问其intValue方法。
下面我们介绍如何自己定义一个泛型类。其语法描述如下:
@interface class_name < __covariant type_identifier > inherit_expression
这里,class_name就是类名;type_identifier是类型标识符,该标识符可以由程序员自己命名;最后的inherit_expression表示继承某个父类以及/或实现某些协议。
这里引入了一个新的关键字——__covariant,表示后面的type_identifier是一个泛型类型。该泛型类型在声明一个对象时进行具体指明。
下面举一个具体的例子来说明如何具体使用Objective-C泛型。
@interface MyObject<__covariant T> : NSObject
{
@private T obj;
}
@property (nonatomic, retain) T obj;
@end @implementation MyObject @synthesize obj; - (void)dealloc
{
if(obj != nil)
[obj release]; NSLog(@"My object deallocated!");
[super dealloc];
} @end @implementation ViewController - (void)viewDidLoad { MyObject<NSNumber*> *numObj = [[MyObject alloc] init];
numObj.obj = @;
[numObj release]; MyObject<NSString*> *strObj = [[MyObject alloc] init];
strObj.obj = @"Hello, world";
[strObj release];
} @end
上述代码,我们定义了一个MyObject的泛型类,其泛型标识符用T表示。随后,我们用该泛型T定义了一个私有对象obj,并用它作为一个property。
随后,我们在viewDidLoad方法里用MyObject<NSNumber*>声明了一个对象numObj;用MyObject<NSString*>声明了一个strObj对象。我们后面可以直接通过numObj.obj调用intValue来访问其int值;直接通过strObj.obj来调用length方法以获得其字符串长度。
Objective-C轻量级泛型的更多相关文章
- iOS开发——新特性OC篇&Objective新特性
Objective新特性 Overview 自 WWDC 2015 推出和开源 Swift 2.0 后,大家对 Swift 的热情又一次高涨起来,在羡慕创业公司的朋友们大谈 Swift 新特性的同时, ...
- nullable,kindof,泛型新特性
文章来自: http://blog.csdn.net/majiakun1/article/details/46530245 Overview 自 WWDC 2015 推出和开源 Swift 2.0 后 ...
- Objective-C的泛型
WWDC2015的明星是Swift.在Swift语言到2.0以后会被开源,这其中包括了protocol扩展和一个新的错误处理API. 苹果的小baby已经长成,并且意料之中的获得了开发者的关注.但是在 ...
- Swift & OC 混编 浅析
转载自:http://www.infoq.com/cn/articles/wangyi-cartoon-swift-mixed-practice?utm_campaign=rightbar_v2&am ...
- 2015 Objective-C 三大新特性
Overview 自 WWDC 2015 推出和开源 Swift 2.0 后,大家对 Swift 的热情又一次高涨起来,在羡慕创业公司的朋友们大谈 Swift 新特性的同时,也有很多像我一样工作上依然 ...
- 【转载】2015 Objective-C 三大新特性 | 干货
Overview 自 WWDC 2015 推出和开源 Swift 2.0 后,大家对 Swift 的热情又一次高涨起来,在羡慕创业公司的朋友们大谈 Swift 新特性的同时,也有很多像我一样工作上依然 ...
- Objective-C 语言特点/特性
Objective-C中 1.所有的类都必须继承自NSObject. 2.所有对象都是指针的形式. 3.用self代替this. 4.使用id代替void*. 5.使用nil表示NULL, 6.只支持 ...
- ios学习路线—Objective-C(新特性)
1.方法顺序无关 Objective-C类由声明文件h和实现文件m组成,所有的public方法都在h文件中声明,private方法可以写在m文件中,但是在早期的编译环境中需要注意方法的顺序,例如下面的 ...
- YYModel源代码阅读--基础知识
这段时间因为工作需要,阅读了YYModel这个开源框架,至于它能做什么,最直白的讲述就是JSON与Model之间的相互转化. 源代码在Github,大家可以自行git clone或者download. ...
随机推荐
- PAT1016 × PAT1017
本次题解是综合1016和1017两道题来讲解,原因无他,因为这两道都是模拟题,综合字符串处理.排序等考点 接手一道模拟题,一定要快速且准确地了解模拟的过程,清晰题目涉及的关键信息.比如1016要计算电 ...
- P2015 二叉苹果树[树形dp+背包]
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...
- 《代码敲不队》第九次团队作业:Beta冲刺第1天
项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 作业链接地址 团队名称 代码敲不队 作业学习目标 (1)项目文档的完善与整理:(2)团队项目总结陈述PPT编制:(3)符合 ...
- 关于equals和hashcode问题
默认情况下也就是从超类Object继承而来的equals方法与‘==’是完全等价的,比较的都是对象的内存地址,但我们可以重写equals方法,使其按照我们的需求的方式进行比较,如String类重写了e ...
- java 利用反射调用静态方法的示例
内容简介 主要介绍使用反射的机制来调用执行类中的静态方法. 静态方法 public class GisUtil { private final static Logger logger = Logge ...
- mysqldump 原理(转载)
mysqldump 备份过程可以描述为: (1) 先发出一条 flush tables 关闭实例上所有打开的表(2) 创建一个全局锁,FLUSH TABLES WITH READ LOCK获得 db ...
- vue中插槽作用域的使用
一.插槽作用域 1.简单来说就是带参数的插槽: 2.使用方式: 在组件标签内部加一个template标签 在template标签上加一个属性scope 值随意书写 在组件内部用slot进行接受,如果给 ...
- Mybatis 入门 (二)
1. Mapper配置文件处理特殊字符 用 > 和 &It; 代替 > 和 < 2. 延迟加载 单表查询性能比多表关联查询要高得多,即先查询单表,如果需要关联多表时再进行查询 ...
- RookeyFrame 模块 线上创建的模块 迁移到 线下来
1. 把线上创建的model,写在项目的model层里面. 把文件 Rookey.Frame.Web\Config\TempModel\Order_File.code 复制到model层, 用文本编辑 ...
- C位运算符的使用
#include <stdio.h> int main(void) { //位运算符 & | ^ ~ printf("8|2=%d\n",8|2);// 10 ...