id and instancetype id 和 instancetype

Objective- C 的安全漏洞有很大一部分归咎于 id 这个数据类型。这个数据类型的意思是「任意 Objective- C 对象」。确切地说,它是一个指针,这个指针可以指向任意的对象,更夸张的是不用在前面加星号。

它看起来很像是 Swift 里的 AnyObject,感觉是一个完美的数据类型,但是 Objective- C 里的 id ,跟 AnyObject 完全不一样。

id 的存在是因为 Objective- C 最近才有了泛型这个概念。用它可以转换数组元素的数据类型。与其说 id 代表的是任意对象,不如说它代表的是每一个对象。你可以在上面使用任意数组方法,字符串方法,数值方法,编译器都会默认是可行的,但是当程序运行时就会发生崩溃,但你不会知道这个崩溃是怎么回事。

我们来下面的代码:

NSArray *foo = [NSArray new];
id bar = foo;
NSArray *baz = bar;

这行代码创建了一个 foo 数组,接着创建了一个 id 类型的变量 bar,并且把 foo 数组赋值给了 bar。接着创建了一个新的 NSArray 类 baz。代码看起来是可行的,没有提示也没有错误,但这里的类型都是不安全的,隐藏了非常多问题。

在2012年之前,很多的初始化器会直接返回 id 数据类型。举个例子,[NSSet setWithObjects:@"foo", nil]; 这个方法,不会返回 NSSet,而是返回 id ,也就是说你最初所设定的数据类型,会因为这个方法而改变。

在2012年之后,程序员可以用 instancetype 来代替 id 。instancetype 的意思「返回当前类对应的实例」,以确保编译器正确地使用数据类型。苹果花了很长时间来更新自己的 API,目前这个更新已经完成了,几乎所有的方法都都用了 instancetype。但是在一些年代比较久远的项目里,你可能还是要和 id 打交道。

results matching ""

    No results matching ""