iOS自定义初始化方法

有很多初始化方法我们通常都是在applicationDidFinishLaunching里一个个调用,那么有没有办法像__attribute__((constructor)),能够自动调用被修饰的函数?

可以通过指定函数所在section的方式,然后获取section开头去逐个调用。但是这种方法有个问题,你只能获取到第一个函数的开头,但是你不知道它的大小,也就没有办法去依次获取了。

__attribute__((used, section("__TEXT, CustomInit")))
void custom1() {NSLog(@"custom1");
}__attribute__((used, section("__TEXT, CustomInit")))
void custom2() {NSLog(@"custom2");
}- (void)callCustom
{Method orginalMethod = class_getClassMethod([self class], _cmd);IMP imp = method_getImplementation(orginalMethod);Dl_info info;if (dladdr((void *)imp, &info)) {printf("dli_fname: %s\n", info.dli_fname);printf("dli_sname: %s\n", info.dli_sname);printf("dli_fbase: %p\n", info.dli_fbase);printf("dli_saddr: %p\n", info.dli_saddr);} else {printf("error: can't find that symbol.\n");}unsigned long funcSize = 0;//CustomFunc段的开始uint8_t *funcStart = getsectiondata((struct mach_header_64 *)info.dli_fbase, "__TEXT", "CustomInit", &funcSize);((void(*)())funcStart)();
}

所以可以通过声明全局或者静态指针变量,去持有这些函数,把这些指针放到__DATA里自定义的一个段里,因为指针大小都是8字节,每次跳8字节就能访问到下一个指针了。

void custom1() {NSLog(@"custom1");
}void(*customVar1)(void) __attribute__((used, section("__TEXT, CustomInit")))  = custom1;void custom2() {NSLog(@"custom2");
}void(*customVar2)(void) __attribute__((used, section("__TEXT, CustomInit")))  = custom1;- (void)callCustom
{Method orginalMethod = class_getClassMethod([self class], _cmd);IMP imp = method_getImplementation(orginalMethod);Dl_info info;if (dladdr((void *)imp, &info)) {printf("dli_fname: %s\n", info.dli_fname);printf("dli_sname: %s\n", info.dli_sname);printf("dli_fbase: %p\n", info.dli_fbase);printf("dli_saddr: %p\n", info.dli_saddr);} else {printf("error: can't find that symbol.\n");}unsigned long size = 0;uint8_t *start = getsectiondata((struct mach_header_64 *)info.dli_fbase, "__DATA", "CustomInit", &size);int funcCount = size/sizeof(void *);for (int i=0;i<funcCount; i++) {//这里要用指针的指针void(**f)() = (void(**)())start + i;(*f)();}
}

这样声明函数和变量太麻烦了,我们可以使用宏来帮忙。

#define CustomInitFuncBegin(funcName) \
void funcName() {#define CustomInitFuncEnd(funcName) }\
static void (*funcName##_var)() __attribute__((used, section("__DATA, CustomInit")))  = funcName;CustomInitFuncBegin(init1)
NSLog("测试init1\n");
CustomInitFuncEnd(init1)CustomInitFuncBegin(init2);
NSLog("测试init2\n");
CustomInitFuncEnd(init2);+ (void)callCustom
{Method orginalMethod = class_getClassMethod([self class], _cmd);IMP imp = method_getImplementation(orginalMethod);Dl_info info;if (dladdr((void *)imp, &info)) {printf("dli_fname: %s\n", info.dli_fname);printf("dli_sname: %s\n", info.dli_sname);printf("dli_fbase: %p\n", info.dli_fbase);printf("dli_saddr: %p\n", info.dli_saddr);} else {printf("error: can't find that symbol.\n");}unsigned long size = 0;uint8_t *start = getsectiondata((struct mach_header_64 *)info.dli_fbase, "__DATA", "CustomInit", &size);int funcCount = size/sizeof(void *);for (int i=0;i<funcCount; i++) {void(**f)() = (void(**)())start + i;(*f)();}
}

参考:

https://everettjf.github.io/2017/03/06/a-method-of-delay-premain-code/

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java】JDK1.8 HashMap源码,put源码详细讲解

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 在Java中&#xff0c;HashMap结构是被经常使用的&#xff0c;在面试当中也是经常会被问到的。这篇文章我给大家分享一下我对于HashMap结构源码的理解。 HashMap的存储与一般的数组不同&#xff0c;HashMap的每一个元素存…

第 9 场 小白入门赛 -- 蓝桥杯

比赛地址 第 9 场 小白入门赛 - 蓝桥云课 1 . 省赛总动员 #include <iostream> using namespace std; int main() {// 请在此输入您的代码cout << "No.1" << endl ;return 0; } 2 . 盖印章 解方程即可&#xff0c;因为题目确定有解 #include…

libevent源码解析-定时机制,信号处理,流量控制

概述 libevent的event&#xff0c;event_callback&#xff0c;event_base除了可以用来支持套接字的自动和手动分发&#xff0c;也可用来支持定时机制&#xff0c;信号处理&#xff0e;这里&#xff0c;我们补充对定时机制&#xff0c;信号处理的分析&#xff0e; libevent中的…

c# wpf datagrid 简单试验

1.概要 datagrid 一个列表类的控件 2.代码 <Window x:Class"WpfApp2.Window3"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.mic…

MySOL之旅--------MySQL数据库基础( 3 )

本篇碎碎念:要相信啊,胜利就在前方,要是因为一点小事就停滞不前,可能你也不适合获取胜利,成功的路上会伴有泥石,但是走到最后,你会发现身上的泥泞皆是荣耀的勋章! 今日份励志文案: 凡是发生皆有利于我 目录 查询(select) 1.全列查询 2.指定列查询 3.查询字段为表达式 ​编…

嵌入式中常用的巧妙方法 - (汇总)

概述 做项目&#xff0c;掌握以下方法&#xff0c;可提高开发效率&#xff0c;把时间全部放在需求上。 1、快速获取结构体成员大小 #include <stdio.h> // 获取结构体成员大小 #define GET_MEMBER_SIZE(type, member) sizeof(((type*)0)->member)// 获取结构体成…

每日一题:C语言经典例题之杨辉三角

题目描述 输出杨辉三角形。 输入 第一行输入一个整数 n (1<n<10)。 输出 输出杨辉三角形的前n行&#xff0c;每个数字占8格左对齐。 样例输入 4 样例输出 1 1 1 1 2 1 1 3 3 1 代码&#xff1a; #inc…

前端小白学习Vue框架(二)

一.属性计算、属性监听、属性过滤 1.认识MVVM V &#xff08;用户视图界面&#xff09;通过VM (应用程序) 向Model(数据模型) 取值与赋值的过程&#xff01; 数据双向绑定 视图改变更新数据&#xff0c;数据改变更新视图 2.属性计算 //在vue实例中通过computed去计算new …

SNRO 编号范围对象管控,唯一ID

事务代码:SNRO 代码引用: DATA: MAXTID TYPE I,NEWNO TYPE CHAR8. CALL FUNCTION NUMBER_RANGE_ENQUEUE EXPORTING OBJECT ZQC57 EXCEPTIONS FOREIGN_LOCK 1 OBJECT_NOT_FOUND 2 SYSTEM_FAILURE 3 OTHERS …

Flutter学习13 - Widget

1、Flutter中常用 Widget 2、StatelessWidget 和 StateFulWidget Flutter 中的 widget 有很多&#xff0c;但主要分两种&#xff1a; StatelessWidget无状态的 widget如果一个 widget 是最终的或不可变的&#xff0c;那么它就是无状态的StatefulWidget有状态的 widget如果一个…

vLLM部署Qwen1.5-32B-Chat

vLLM部署Qwen1.5-32B-Chat 部署环境 操作系统:Ubuntu 20.04.2 LTS Docker:v24.0.0 Docker Compose:v2.17.3 GPU:NVIDIA A100-SXM4-80GB Nvidia Driver Version: 535.154.05 CUDA Version: 12.2 部署过程 模型文件下载 下载地址:通义千问1.5-32B-对话 模型库 (m…

【已解决】解决前端模块与Node.js版本不兼容问题

目录 一、问题描述&#xff1a; 二、问题定位 三、解决方案 3.1 安装一个兼容版本的Node.js&#xff1a; 1 安装node 2 安装nvm 3.2 更新node-ipc模块&#xff1a; 3.3 使用--force选项&#xff08;不推荐&#xff09;&#xff1a; 3.4 寻找替代模块&#xff1a; 一、…

论软件的三层架构设计,使用三段论写一篇架构设计师的论文

软件的三层架构设计是一种广泛采用的设计模式&#xff0c;它通过将应用程序划分为三个主要层次——表示层、业务逻辑层和数据访问层——来提高软件的可维护性、可扩展性和解耦性。本文将采用三段论的方法&#xff0c;深入探讨这一设计模式的理论基础、具体设计原则及其实际应用…

使用echarts控件,小程序分包处理上传失败

原因&#xff1a;在小程序中想要使用echarts控件&#xff0c;但是上传代码失败&#xff0c;错误码为主包超过2.5M&#xff0c;基于此&#xff0c;我们使用分包处理&#xff0c;并上传版本。 错误&#xff1a; 使用echarts&#xff1a;在小程序中引入echarts相关文件。 解决方式…

Arduino 项目笔记 |TH1621 LCD液晶显示屏驱动(SSOP-24封装)

LCD液晶屏资料 LCD液晶屏资料 重要参数&#xff1a; 工作电压&#xff1a; 3V可视角度&#xff1a;1201/4 &#xff0c;1/3 TH1621 驱动 HT1621 LCD控制驱动芯片介绍 VLCD 和 VCC 电压符合规格书&#xff0c;最好都取3.3V 。电压太高或太低都会出现段码液晶屏乱码的情况&am…

vue 原理【详解】MVVM、响应式、模板编译、虚拟节点 vDom、diff 算法

vue 的设计模式 —— MVVM M —— Model 模型&#xff0c;即数据V —— View 视图&#xff0c;即DOM渲染VM —— ViewModel 视图模型&#xff0c;用于实现Model和View的通信&#xff0c;即数据改变驱动视图渲染&#xff0c;监听视图事件修改数据 初次渲染 将模板编译为 render …

【Mybatis-Plus】Mybatis-Plus增删改查示例

示例一&#xff1a;delete 这个删除&#xff0c;是我们直接可以把这条记录给放进去&#xff0c;那么这条记录里面如果说有的属性为空的话&#xff0c;它是不会去管的&#xff0c;但是有些属性它不为空的话&#xff0c;那么它就会根据属性。作为一个equal的条件去做一个删除的一…

msvcr120.dll丢失的解决办法,msvcr120.dll文件丢失的相关介绍

今天小编在使用电脑的时候&#xff0c;突然弹出了一个关于msvcr120.dll文件丢失的问题&#xff01;当出现这种情况时&#xff0c;相信大家都会感到困惑吧&#xff1f;不过&#xff0c;别担心&#xff01;下面就来和大家分享一下解决msvcr120.dll文件丢失问题的几种方法&#xf…

城市内涝与海绵城市规划设计中的水文水动力模拟

原文链接&#xff1a;城市内涝与海绵城市规划设计中的水文水动力模拟https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247601198&idx5&sn35b9e5e3961ea2f190f9742236a7217f&chksmfa820dc9cdf584df97633f64d19bdc3e5f7d1a5a85000c8f040e1953c51b9b39c87b5…

【PyQt】读取MySQL数据填充到Qt表格控件中

说明&#xff1a;代码是从项目源代码中抽取&#xff0c;需要进行适应性修改&#xff0c;不保证可运行。 1 读取MySQL数据库 需要提前安装 pymysql 库。 简单版本&#xff1a; # 需安装 pymysql 库 import pymysql import systry:con pymysql.connect(hostlocalhost, port3…