zoukankan      html  css  js  c++  java
  • 刨根问底:对于 self = [super init] 的思考

    原文:http://ios.jobbole.com/84348/

    对象初始化有两种方式:[class new] 与 [[class alloc] init]

    对于后者,有分配和初始化的过程,alloc 从应用程序的虚拟地址空间上为该对象分配足够的内存,并且将新对象的引用计数加1、将对象的成员变量初始为零,init 会做真正的初使化工作,为对象的实例变量赋予合理有用的值。

    一般不推荐使用[class new],而推荐使用[[class alloc] new],查看源码分析一下:

    发现[class new]默认调用 [newObject init]方法,那么我们无法使用自定义的初始化方法,多了更多的局限性。那么[class alloc] init] 会更方便, 当然[class alloc] init] 的设计也是由于历史的原因。

    为啥这么写?

    我们知道alloc返回一个有效的未初始化的对象实例。对于selfalloc 返回的指针,同时可以在所有的方法作用域内访问。

    但是对于 super,它只是一个”编译器指示符”,告诉编译器在父类中搜索方法的实现。

    优先调用[super init] 是为了使超类完成它们自己的初始化工作。

    那么 if (self = [super init])又是做啥?

    这里是担心父类初始化失败,如果初始化一个对象失败,就会返回nil,当返回nil的时候self = [super init]测试的主体就不会再继续执行。如果不这样做,你可能会操作一个不可用的对象,它的行为是不可预测的,最终可能会导致你的程序崩溃。

    理解 Self & Super

    看到网上一道经典的题目:

    self表示当前这个类的对象,而super是一个编译器标示符,和self指向同一个消息接受者。在本例中,无论是[self class]还是[super class],接受消息者都是Son对象,但superself不同的是,self调用class方法时,是在子类Son中查找方法,而super调用class方法时,是在父类Father中查找方法。

    当调用[self class]方法时,会转化为objc_msgSend函数,这个函数定义如下:

    这时候就开始了消息传递和转发的过程,会先从Cache 中查找方法,然后当前类,如果还是查找不到会去父类,直至NSObject

    对于NSObject类中,- (Class)class的实现如下:

    所以打印结果为Son

    当调用[super class]方法时,会转化为objc_msgSendSuper,这个函数定义如下:

    objc_msgSendSuper函数第一个参数super的数据类型是一个指向objc_super的结构体

    结构体包含两个成员,第一个是receiver,表示类的实例。第二个成员是记录当前类的父类是什么,会优先从Father这个类里去找- (Class)class,然后进行消息传递的过程。

    会发现不管是self、还是super指向消息接受者是一样的,并且经过消息传递,最终处理消息的方法都是NSObject中的- (Class)class方法。

  • 相关阅读:
    Can't remove netstandard folder from output path (.net standard)
    website项目的reference问题
    The type exists in both DLLs
    git常用配置
    Map dependencies with code maps
    How to check HTML version of any website
    Bootstrap UI 编辑器
    网上职位要求对照
    Use of implicitly declared global variable
    ResolveUrl in external JavaScript file in asp.net project
  • 原文地址:https://www.cnblogs.com/zxykit/p/5421181.html
Copyright © 2011-2022 走看看