iOS学习笔记(02) - 关键字 __kindof
1.__kindof:表示当前类或它的子类。
2.__kindof书写格式:放在类型前面,表示修饰这个类型。
3.__kindof优点:在调用的时候,很清楚的知道返回类型。
直接举一个例子来形容这个问题。假如我们声明了一个父类 Person ,这个父类有一个构造方法,如下:
1 + (Person *)person { 2 3 return [[self alloc] init]; 4 }
同时在这个父类 Person 的.h头文件中声明这个方法。这样我们在外界使用 Person 调用这个构造方法,返回的值肯定为 Person * 类型,毋庸置疑。
我们再声明一个子类 SonOfPerson ,这样,我们在外界调用这个方法的时候,就会出现这样一个问题:
通过上面的方法的实现,我们是知道这个方法返回的对象是 SonOfPerson 子类的类型的,但是编译器不知道,所以它提示我们一个 SonOfPerson 的指针类型指向了一个 Person 的对象。我们只能通过强制转换来让编译器不出现这样的警告。
有什么办法能解决这个问题吗?
1.使用 id 或 instancetype 类型。也就是这个样子:
1 /* 2 + (id )person { 3 4 return [[self alloc] init]; 5 } 6 */ 7 8 /* 9 + (instancetype)person { 10 11 return [[self alloc] init]; 12 } 13 */
同时在.h中实现相应的方法。但问题随之出现:
我们无法在编译器的提示中看到任何有关返回值的提示。它是个id类型,也就是说可能是任何对象。这样显然是不好的,若你在接口中写了个id对象,不用说你同事在看到这个接口时时如何懵逼,就是过两天你自己看可能都无法想起来这个接口究竟返回值是什么类型,造成不必要的麻烦。这样不好。
同时比较下 id 和 instancetype 两种类型的异同:
1.相同点
都可以作为方法的返回类型。
2.不同点
2.1instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象;
2.2instancetype只能作为返回值,不能像id那样作为参数。
2.使用__kindof:
1 + (__kindof Person *)person { 2 3 return [[self alloc] init]; 4 }
这样我们在使用的时候会这样提示:
这样我们就清楚了,这个返回值类型是 Person 以及它的子类。同时,编译器也知道返回的可能是 Person 的子类,不会再给我们警告了。