美文网首页
建议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

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