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,动态将分类的方法合并到类对象,元类对象中:
- for (i = 0; i < used(); i ++)
根据分类的方法、属性、协议占用内存大小,分别扩充类的:
方法列表mlists、
属性列表proplists、
协议列表protolists
每一种列表都是二维数组,每一个分类相关数据存储在大数组中的小数组 - 通过 memmove(整体移动并覆盖,内部会判断移动方向)移动类对象的方法、属性、协议到最后
- 通过 memcoy(单个移动并覆盖)将分类的方法、属性、协议到类中
- for (i = 0; i < used(); i ++)
- 加载顺序
类,优先于分类加载,源码采用递归方式,保证类加载的优先级
分类之间、类与类之间,先编译的先加载,后编译先调用
添加成员变量
不能直接添加成员变量,但能通过runtime间接添加。property在category中只生成setter和getter方法声明。
- 方案一:
在+load方法中完成全局字典初始化,对属性进行存取,要维护key的唯一性,且有线程安全问题,内存问题(销毁后仍调用) - 方案二:runtime
在setter方法中,调用函数:#import <objc/runtime.h>
在getter方法中,调用函数:objc_setAssociatedObject(self, key , name, objc_ASSOCIATION_ASSIGN)
声明key:return objc_getAssociatedObject(self, key)
- 全局
staitic const void *key = &key;
- 全局
staitic const char key = &key; // char 减小key内存占用
- 一定要给key赋初值,保证key的唯一性
- 这里是把全局变量key的地址值给了key
- static 保证全局变量只可在文件内访问
- 不使用static,在外界可使用extern 读写
- 直接把key替换为常量字符串(直接声明的字符串放在常量区,内存地址不变)
- 直接把key替换为@selector(key). 返回的结构体的指针不变
- 全局
load
调用形式
- 一个类的 load方法在启动时都会且仅被调用一次
- 重写+load,系统调用 ——> 指针访问直接调用
- [Class load],手动调用 ——> 消息机制
系统调用形式的内部原理
- 按照编译顺序,谁在前面就先被编译
- 先调用完所有类的load方法
- 再调用category的load方法
源码实现逻辑
- 通过while循环,判断是否所有类的load方法都被调用
- 通过递归处理,先调用父类+load,再调用子类+load
- 分类通过for ++ 循环,取出load_method调用
- 通过do while循环,完成所有load方法的调用
initialize
调用形式
消息机制调用
tips: objc_msgSend() ——> 该函数底层是使用汇编实现的
- 调用时机
- 类第一次接收到消息时调用,非启动时调用。
- 子类的initialize调用之前,先主动调用父类的initialize,再调用子类的initialize。
- initialize 方法是以懒加载的方式被调用的。
源码核心函数(由上到下依次调用)
- 实例方法:class_getInstanceMethod
- 静态方法:class_getClassMethod (内部调用class_getInstanceMethod)
- if (initialize && !cls->isInitialized) { 递归 _class_initialize(父类) }
如果分类实现了 +initialize
- 覆盖类本身的+initialize调用
- 只执行编译顺序最后那个分类的 + initialize
相关文章:

iOS OC 底层原理之 category、load、initialize
文章目录 category底层结构runtime 执行 category 底层原理添加成员变量 load调用形式系统调用形式的内部原理源码实现逻辑 initialize调用形式源码核心函数(由上到下依次调用)如果分类实现了 initialize category 底层结构 本质是结构体。struct _cat…...

另外知识与网络总结
一、重谈NAT(工作在网络层) 为什么会有NAT 为了解决ipv4地址太少问题,到了公网的末端就会有运营商路由器来构建私网,在不同私网中私有IP可以重复,这就可以缓解IP地址太少问题,但是这就导致私有IP是重复的…...

怎样用云手机进行TikTok矩阵运营?
在运营TikTok矩阵时,许多用户常常面临操作复杂、设备过多等问题。如果你也感到操作繁琐,不妨考虑使用云手机。云手机具备丰富的功能,能够帮助电商卖家快速打造高效的TikTok矩阵。接下来,我们将详细解析这些功能如何提升你的运营效…...

RTMP播放器全解析
一、RTMP 播放器概述 (一)RTMP 播放器的定义与作用 RTMP 播放器是一种专门用于播放采用 RTMP(Real Time Messaging Protocol)协议的视频流的工具。在当今的流媒体播放领域中,它扮演着至关重要的角色。RTMP 播放器能够…...
定期清洗ip是为了什么?怎么清洗iip
定期清洗IP(也称为“IP清理”)的目的是确保使用的IP池保持高效、可靠、安全,避免因使用无效或被封禁的IP导致网络操作失败。尤其在数据爬取、负载均衡等使用代理的场景中,定期清洗IP有助于提升整体的性能和数据抓取成功率。 定期…...

谁能给我一个ai现在无法替代画师的理由?
小白可做!全自动AI影视解说一键成片剪辑工具https://docs.qq.com/doc/DYnl6d0FLdHp0V2ll 如何看待现如今的AI绘画 哎呀玫瑰花来了,所有花式都要玩完了。 我相信大家在网上已经看过了太多惊为天人的AI绘画作品,有人抵制,有人支持&a…...

深入理解MySQL InnoDB中的B+索引机制
目录 一、InnoDB中的B 树索引介绍 二、聚簇索引 (一)使用记录主键值的大小进行排序 页内记录排序 页之间的排序 目录项页的排序 (二)叶子节点存储完整的用户记录 数据即索引 自动创建 (三)聚簇索引…...
语言的输入
编程语言提供最基本的输入输出,输入一个预期的数据也不是看起来那么简单,如下一一展开。 不同输入形式 C语言scanf提供格式串输入,程序员负责配置正确的格式,比如%d整型,%s为字符串。可能出现格式串和变量格式、个数不…...

2024年中国电子学会青少年软件编程(Python)等级考试(二级)核心考点速查卡
考前练习 2024年03月中国电子学会青少年软件编程(Python)等级考试试卷(二级)答案 解析 2024年06月中国电子学会青少年软件编程(Python)等级考试试卷(二级)答案 解析 知识点描述 …...

OpenCV系列教程二:基本图像增强(数值运算)、滤波器(去噪、边缘检测)
文章目录 一、基本图像增强(数值运算)1.1 加法 (cv2.add)1.1.1 图像与标量相加(调节亮度)1.1.2 图像与图像相加(两个图像shape要相同)1.1.3 图像的加权加法(渐变切换&…...

什么是文件完整性监控(FIM)
组织经常使用基于文件的系统来组织、存储和管理信息。文件完整性监控(FIM)是一种用于监控和验证文件和系统完整性的技术,识别用户并提醒用户对文件、文件夹和配置进行未经授权或意外的变更是 FIM 的主要目标,有助于保护关键数据和…...

分库分表还是分布式?如何用 OceanBase的单机分布式一体化从根本上解决问题
随着企业业务规模的不断增长,单机集中式的数据库系统逐渐难以承载企业日益增长的数据存储与处理需求。因此,MySQL 的分库分表方案成为了众多企业应对数据存储量激增及数据处理能力需求扩张的“止痛药”。尽管这一方案短期内有效缓解了企业面临的大规模数…...

怎么查看网站是否被谷歌收录,哪些因素影响着网站是否被谷歌收录
一、怎么查看网站是否被谷歌收录 查看网站是否被谷歌收录,有多种方法可供选择,以下是几种常用的方式: 1.使用“site:”指令: 在谷歌搜索引擎的搜索框中输入“site:你的域名网址”(注意使用英文冒号&#x…...

【RabbitMQ】面试题
在本篇文章中,主要是介绍RabbitMQ一些常见的面试题。对于前几篇文章的代码,都已经在码云中给出,链接是mq-test: 学习RabbitMQ的一些简单案例 (gitee.com),如果存在问题的话欢迎各位提出,望共同进步。 MQ的作用以及应用…...
Python软体中使用TensorFlow实现一个简单的神经网络:从零开始
使用TensorFlow实现一个简单的神经网络:从零开始 在现代数据科学和机器学习领域,神经网络是一个强大的工具。TensorFlow是一个广泛使用的开源库,专门用于机器学习和深度学习。本文将详细介绍如何使用TensorFlow实现一个简单的神经网络。我们将从基础概念开始,逐步深入到代…...

StopWath,apache commons lang3 包下的一个任务执行时间监视器的使用
StopWath是 apache commons lang3 包下的一个任务执行时间监视器,与我们平时常用的秒表的行为比较类似,我们先看一下其中的一些重要方法: <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependen…...

ELMO理论
目录 1 优点 2 缺点 3.知识点个人笔记 2018年3月份,ELMo出世,该paper是NAACL18 Best Paper。在之前2013年的word2vec及2014年的GloVe的工作中,每个词对应一个vector,对于多义词无能为力。ELMo的工作对于此,提出了一…...
EMU 街机模拟器编译方法
安装ubuntu 16.04 下载gcc 8.2 安装 然后安装automake 1.16 ,1.15 安装jdk8 sdk 里面配套的ndk 21e 编译库 cd ~/emu-ex-plus-alpha/imagine/bundle/all/ export IMAGINE_PATH/home/lxm/emu-ex-plus-alpha/imagine export ANDROID_SDK_ROOT/home/lxm/Sdk export ANDROID_NDK_…...
c++开发之编译curl(windows版本)
在 Windows 上编译支持 OpenSSL 的 cURL 库并不简单,因为涉及到多个库的依赖关系以及工具链的配置。以下是编译支持 OpenSSL 的 cURL 库的详尽步骤: 环境要求 编译工具链: MinGW 或 Visual StudioCMakePerl (用于编译 OpenSSL)NASM (用于编译…...

IT运维挑战与对策:构建高效一体化运维管理体系
在当今数字化时代,IT运维作为企业运营的核心支撑,其重要性不言而喻。然而,随着业务规模的扩大和技术的不断革新,IT运维团队面临着前所未有的挑战。本文旨在深度剖析当前IT运维中存在的主要问题,并探索一体化解决方案&a…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...