美文网首页
建议5:iOS处理隐藏的返回类型,优先选择实例类型而非id

建议5:iOS处理隐藏的返回类型,优先选择实例类型而非id

作者: 花生儿 | 来源:发表于2016-04-25 00:37 被阅读170次

实例类型(instance)是oc语言中新添加的一个返回类型,实例类型作为方法返回的实例的类型,是苹果在2013年的年度大会上宣布的。这个新添加的实例类型不仅可以用来作为oc方法的返回类型,且能用这个实例类型来作为向编译器的提示,提示方法返回的类型将是方法所属类的实例。

类的实例,作为方法返回类型,宜采用关键字instancetype作为方法的返回类型,如alloc,init和类工厂方法等。使用instancetype作为类(或者类的子类)的实例返回类型,可以大大改善oc代码的类型安全。例如,考虑下面代码:

@interface MyObject : NSObject 
+ (instancetype)factoryMethodA;
+ (id)factoryMehtodB;
@end
@implementation MyObject
+ (instancetype)factoryMehtodA {
    return [[[ self class] alloc]init];
}
+ (id)factoryMehtodB {
    return [[[self class]alloc]init];
}
@end 
void doSomething() {
     NSUInterger x,y;
     x = [[MyObject factoryMehtodA] count];
     y = [[MyObject factoryMethodB] count];
}

通过以上的代码可以看到,instancetype作为+factoryMethodA的返回类型,也就是说,该消息的类型表达式是MyObject* 。danshi MyObject由于先天缺乏一个-count方法,编译器将会对此给出一个关于x行的警告。对于这样的情况,如果把instancetype换成id作为实例的方法返回类型,也就是如上面代码的实例,id作为方法+factoryMethodB的返回类型。在编译器编译的过程中不会发出关于y行的警告。

为什么编译器没有发出没有给出警告?因为id类型的对象可以作为任何类,并且调用的方法-count在一些类中存在,故此向编译器发出方法+factoryMethodB返回值事项了-count的信息,从而编译器没有给出警告。对于该种编写代码的方法,在无形中埋下了隐患。

为了确保instancetype工厂方法有正确的子类行为,一定要使用[self class]分配类,而不是直接饮用类名。遵循这个惯例,记住,务必要使编译器能正确地推断出子类类型。例如,依据前面的示例,考虑尝试做一个前面MyObject子类示例:

@interface MyObjectSubClass : MyObject
@end 
void doSomethingElse () {
       NSString * aString = [MyObjectSubclass factoryMethodA];
  }

对于上述代码,编译器将会发出警告。
在该示例中,+factoryMethodA消息发送之后,将返回一个类型MyObjectSubClass的对象实例。编译器就能恰当的确定+factoryMehtodA的返回类型应该是子类MyObjectSubClass,而不是工厂方法中所声明的超类。

在编写代码中,通常在处理init方法和类工厂方法时,宜用instancetype类替换id作为返回值。在新版的Xcode5中,虽然,编译器会自动地把alloc,init,new方法之中的id转换为instancetype类型,但对于这几种方法之外的其他方法,编译器则不会进行转化。在oc的公约之中,明确地建议对所有方法尽可能的使用isntancetype。也就是说,作为返回值,id由于自身的缺陷,会在oc中逐渐退出,由isntancetype来代替。

注意,仅有在作为返回值的时候,宜用instancetype来替换id。而不是代替代码中的所有的id。与id不同,instancetype关键字仅能作为方法声明的返回类型。也即是说,在某一特定却与,isntancetype可以代替id。并不是所有区域都可以代替。

要点######

(1)instancetype仅仅用来作为oc方法的返回类型.
(2)使用instancetype可避免隐式转换id而造成的欺骗性编译无误通过的现象,防止程序正式运行时候出现崩溃现象。可以大大改善oc代码的类型安全。
(3)在某一特定区域,instancetype可以替代id,并不是所有区域都可以替代id。

相关文章

  • 建议5:iOS处理隐藏的返回类型,优先选择实例类型而非id

    实例类型(instance)是oc语言中新添加的一个返回类型,实例类型作为方法返回的实例的类型,是苹果在2013年...

  • 自定义初始化方法

    尽量使用 instancetype 而不是 id 作为实例化函数的返回类型 instancetype 返回的类型是...

  • ios10兼容记录

    NSMutableDictionary处理 返回默认类型有所调整,afnetworking本身可以把id类型的re...

  • ios开发--instancetype

    推荐所有以前使用id作为返回类型的工厂方法和init方法应改用instancetype为返回类型。 使用id类型回...

  • Swift编程二十四(不透明类型)

    案例代码下载 不透明的类型 函数或方法返回的不透明类型会隐藏其返回值的类型信息。不是提供具体类型作为函数的返回类型...

  • Swift - 不透明类型

    不透明类型 具有不透明返回类型的函数或方法会隐藏返回值的类型信息。函数不再提供具体的类型作为返回类型,而是根据它支...

  • java中enum枚举类型

    枚举类型常用方法:values()返回枚举类型定义数组ordinal()返回实例在枚举类型定义的次序,默认从0开始...

  • Swift知识点27 - 不透明类型

    具有不透明返回类型的函数或方法会隐藏返回值的类型信息。函数不再提供具体的类型作为返回类型,而是根据它支持 的协议来...

  • swift学习

    检查类型 用类型检查操作符( is )来检查一个实例是否属于特定子类型。若实例属于那个子类型,类型检查操作符返回 ...

  • instancetype和id的区别

    1、instancetype在编译期确定实例的类型,id在编译期不检查类型,运行时检查类型。2、id可以作为方法的...

网友评论

      本文标题:建议5:iOS处理隐藏的返回类型,优先选择实例类型而非id

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