IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Objective-C——initialize方法调用原理分析 -> 正文阅读

[移动开发]Objective-C——initialize方法调用原理分析

一、调用时机

在类第一次接收到消息的时候调用

二、调用顺序

  • 先调用父类的initialize方法,再调用子类的initialize方法(递归,每个类只会初始化一次)
  • 如果子类没有实现initialize方法,则会调用父类的initialize方法(消息调用机制,通过superclass指针向上查找)(所以,父类的initialize方法可能会被调用多次)
  • 如果分类实现了initialize方法,会“覆盖”类本身的initialize调用(方法合并的时候,分类的方法更靠前)

三、源码窥探

// objc-initialize.mm
/***********************************************************************
* class_initialize.  Send the '+initialize' message on demand to any
* uninitialized class. Force initialization of superclasses first.
**********************************************************************/
void initializeNonMetaClass(Class cls) {
    ASSERT(!cls->isMetaClass());
    Class supercls;
    bool reallyInitialize = NO;
    // Make sure super is done initializing BEFORE beginning to initialize cls.
    // See note about deadlock above.
    supercls = cls->superclass;
    // 如果有父类,并且父类没有完成初始化
    if (supercls  &&  !supercls->isInitialized()) {
        // 递归初始化父类
        initializeNonMetaClass(supercls);
    }
    // 如果类没有完成初始化,并且不是正在初始化,标记成准备初始化
    if (!cls->isInitialized() && !cls->isInitializing()) {
        cls->setInitializing();
        reallyInitialize = YES;
    }
    if (reallyInitialize) {
        // 发送initialize消息:
        // ((void(*)(Class, SEL))objc_msgSend)(cls, @selector(initialize));
        callInitialize(cls);
        // Done initializing.
        /*
         // lockAndFinishInitializing 主要做了两件事:
         // 标记完成初始化
         cls->setInitialized();
         // 释放锁
         classInitLock.notifyAll();
         */
        lockAndFinishInitializing(cls, supercls);	
    }
}

四、示例分析(一)

1. 结构图(均实现了initialize方法)

在这里插入图片描述

2. 代码

①:[Person class];
②:[Student class];
③:[GoodStudent class];
④:[NorStudent class];
/// 调用结果
+[Person initialize]
+[Student initialize]
+[GoodStudent initialize]
+[NorStudent initialize]

3. 分析

  • 执行代码①,给Person发消息,Person的父类NBObjcet没有实现initialize方法,所以调用父类的方法,不会有打印信息,接着调用Person类中的initialize方法,打印+[Person initialize]
  • 执行代码②,给Student发消息,先看父类Person是否初始化,因为父类已经初始化,所以调用Student类的initialize方法,打印+[Student initialize]
  • 执行代码③,给GoodStudent发消息,先看父类Student是否初始化,代码执行逻辑同上
  • 执行代码④,给NorStudent发消息,代码执行逻辑同上

4. 总结

  1. 先调用父类的initialize方法,再调用子类的initialize方法
  2. 每个类只会初始化一次

五、实例分析(二)

1. 结构图(部分实现了initialize方法)

在这里插入图片描述

2. 代码

①:[Person class];
②:[Student class];
③:[GoodStudent class];
④:[NorStudent class];
/// 调用结果
+[Person initialize]
+[Student initialize]
+[Student initialize]
+[NorStudent initialize]

3. 分析

  • 代码①、②的执行逻辑同上

  • 执行代码③的逻辑如下图:
    在这里插入图片描述

    所以,Student的initialize方法会执行两次。

4. 总结

  1. 如果子类没有实现initialize方法,则会调用父类的initialize方法
  2. 父类的initialize方法可能会被调用多次
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-02-26 11:42:07  更:2022-02-26 11:43:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 15:31:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码