iOS 组件二进制与源码查看及调试方案

news2024/10/6 18:26:17

好久没有写文章了这里记录一下把项目代码二进制化提高编译效率的整个过程中碰到的问题和解决方案
先提一下优化编译速度的基本方向基本就是从不同的编译阶段来出主意,比如:

  1. 预编译阶段的头文件查找:
    一款可以让大型iOS工程编译速度提升50%的工具
  2. 利用cocoapods管理工具生成静态库,减少编译时间。
  3. 资源文件整合,减少copy所需时间。

等等。

iOS组件二进制方案

现有iOS组件二进制方案:
  1. Carthage
    iOS的另外一个包管理器,Carthage可以将一部分不常变的库打包成framework,再引如到主工程,这样可以减少开发过程中的编译时间。Carthage 可以比较方便地调试源码,不过从目前角度来说对业务侵入太高
  2. Cocoapods-Binary(Cocoapods 官方推荐的二进制插件)
    单私有源,无法实现服务端缓存,在没有对应二进制包版本时,pod install 后会额外去做二进制包的生成,一定程度上会影响 pod install的速度。开发者切回源码调试,二进制缓存会一并清空,需求重新编译。只支持framework,对我们项目现状需要比较大的头文件引用方式改动
  3. Cocoapods-imy-bin (Cocoapods-bin的升级版)
    该插件进行二进制化的策略是采用双私有源,即2个源地址,一个静态服务器保存预先打好包的framework,一个是我们现在保存源码的服务地址,在install的时候去选择使用下载那个。虽然这个插件在使用上确实会有各种各样的问题,但是自己再此基础之上再改改源码还是很不错的,不然全部重新自己写都不知道要写到啥时候去了。在这里感谢美柚老哥们的开源。

基本确定使用双私有源的方案,因为单私有源的方案除了上面的问题以外,还需要对现有所有podspec进行改造,让目前所有组件的podspec同时支持源码和二进制,做法就是新增subspec:Binary,设置podspec中的–default-spec:Binary,然后把原来的source更新成subspec,但是在组件开发的时候需要肯定要切换到源码的方式,然而podspec文件是肯定的要纳入git管理的,这样会导致整个开发流程严重的依赖使用者的手动管理。因为这里面还有一个非常关键的源码和二进制切换的问题。

插件打包工作流程
业务使用流程:

全自动依赖二进制库,只要远端有,如果没有相应的二进制库则使用源码库来源码打包,业务使用无感知。

源码调试工作原理

iOS组件二进制完以后在debug的时候看到的都是arm64汇编代码,非常不利于查找bug的产生原因,因此需要提供一套源码与二进制及时调试的方案。下面提到的方案都是能在debug状态下实时进行源码调试的,至于那种通过pod install来切换PodA.的bin和source的方案,不在此描述了,因为这个插件自带了,但是说实话这个方案很难满足开发需求。
目前我了解到的实时的源码调试方案有两套。

  1. 一套是美团ZSource背后那些事
    重点是在下面这种图,debug生成的macho文件是带有debug信息的,都在_debug_str段展示出来了,只要你在相应的目录下放入特定的源码文件可以在debug的时候无缝切换源码查看了。这个其实和release版本生成的dsym功能是类似的。

  2. 另外一套就是使用lldb自带的命令把源码的路径和二进制包的路径进行map,这里可能需要写一些脚本。两套方案其实大同小异了。

源码查看方案

以上方案只能解决二进制代码转到源码进行调试,无法解决源码查看的需求,实际应用中我们肯定是有大量的源码查看需求的,甚至比源码调试还多。目前有一套我个人感觉比较完美的方案,就是在工程中同时集成SourcePods,二进制Pods和主工程,但是源码Pods不纳入编译的整体流程(需要改造一下cocoapods),然后使用lldb的map命令将编译流程中的二进制代码地址映射到源码仓,这样就能完美的保留工程二进制化前通过点击代码定义就能跳转到源码仓查看源代码,又能在代码调试断点能跳入sourcepods仓中。

二进制化过程中碰到的问题

问题1:环境宏

iOS中宏是预编译阶段就会被完全替换的,所以目前依赖于特定的环境宏,比如Debug,is_DEV的组件代码在编译成二进制会只包含某个特定环境下的代码,比如archive打出来的包肯定没有debug宏包含的相关代码,所以这样的组件在不同打包环境下是不可以通用的。会报出一些符号undefined的错误。
解决方案:
抽离所有的环境宏到一个特定的组件中,将对环境变量宏的引用改成对组件中的方法调用,比如#is_dev 改成使用[xxx is_dev],但是这个方案改造量比较大,而且有些第三方组件会使用Debug宏,这些也需要同时被改造。

问题2:podspec中的subspec模块怎么处理

目前工程中有好几个组件的podspec都使用了大量的subspec,这就引发了一个问题,是对每个组件的每个子组件生成一个二进制包还是只对一整个podspec生成一个二进制包,对每个子组件生成一个二进制包的好处就是使用podA/subspec的部分引入的时候只会引入一个子组件二进制包,不过其实链接静态库采用的策略本身就是按需引入,所以其实使用组件包和子组件包最终代码大小上不会有区别。但是由于对静态库符号的查找的时候采用的是遍历,所以对链接时间可能会有一点影响。最终我自己选择了生成一个大的二进制包,避免麻烦,并且和xcode目前的编译系统保持了一致。

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

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

相关文章

[附源码]Node.js计算机毕业设计大学生心理咨询系统Express

项目运行 环境配置: Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术: Express框架 Node.js Vue 等等组成,B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境:最好是Nodejs最新版,我…

无法安装vmnet8虚拟网络适配器、vmware network editor未响应、注册失败,请检查账号数据库配置是否正确的解决

文章目录虚拟网络适配器安装 | vmware network editor未响应注册失败,请检查账号数据库配置是否正确的解决关于第一次安装虚拟机的全文约 423 字,预计阅读时长: 2分钟虚拟网络适配器安装 | vmware network editor未响应 原因:卸载…

JDK8 ThreadLocal 源码解析与最佳实践

文章目录用法Example1Example2Springboot Transcation 注解的原理Entry 的 Key 设置为弱引用有什么好处内存泄漏问题为什么 ThreadLocal 不需要 ReferenceQueueget()getEntrygetEntryAfterMissThis class provides thread-local variables. These variables differ from their …

路径规划|多目标海洋捕食者算法(MOMPA)求解最短路径问题(Matlab代码实现)

💥💥💥💞💞💞欢迎来到本博客❤️❤️❤️💥💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清…

LabVIEW在面向对象编程中利用硬件抽象层(HAL)设计1

LabVIEW在面向对象编程中利用硬件抽象层(HAL)设计1 LabVIEW面向对象编程(OOP)采用仪器为中心的硬件抽象层(HAL),使用面向对象的设计模式,可以部署一个仪器重用库,该库可以随着需求和仪器趋势的变化而增长,同时在不可避免的硬件过…

【Redis】主从复制

一、简介 1、什么是主从复制 主机数据更新后根据配置和策略,自动同步到备机的master/slave机制,Matser以写为主,Slave以读为主,简单来说如下图 2、主从复制的好处 读写分离:Matser以写为主,Slave以读为主…

指针的初步认识

🏖️作者:malloc不出对象 ⛺专栏:《初识C语言》 👦个人简介:一名双非本科院校大二在读的科班编程菜鸟,努力编程只为赶上各位大佬的步伐🙈🙈 目录前言一、指针是什么1.1 如何理解编址…

《深入分布式缓存-从原理到实践》笔记

《深入分布式缓存-从原理到实践》笔记 笔记作者:arthury.dy.lee 日期:2018.12.05 笔记只是本人觉得重要的部分的一些摘要或总结,更侧重于后5章。其它更详细内容,请自行买书阅读。 文章目录《深入分布式缓存-从原理到实践》笔记…

【Linux C】线程简单介绍

线程的概念 基本概念 进程:是指⼀个内存中运⾏的应⽤程序,每个进程都有⼀个独⽴的内存空间,⼀个应⽤程序可以同时运⾏多个进程;进程也是程序的⼀次执⾏过程,是系统运⾏程序的基本单位;系统运⾏⼀个程序即…

时序预测 | MATLAB实现具有外生回归变量的ARIMAX时间序列预测(含AR、MA、ARIMA、SARIMA、VAR对比)

时序预测 | MATLAB实现具有外生回归变量的ARIMAX时间序列预测(含AR、MA、ARIMA、SARIMA、VAR对比) 目录 时序预测 | MATLAB实现具有外生回归变量的ARIMAX时间序列预测(含AR、MA、ARIMA、SARIMA、VAR对比)预测效果基本介绍程序设计ARMAARMAARIMASARIMAARIMAXVAR参考资料预测效果…

LC-6260. 矩阵查询可获得的最大分数(最小堆,并查集+离线(海平面上升问题))【周赛323】

6260. 矩阵查询可获得的最大分数 难度困难7 给你一个大小为 m x n 的整数矩阵 grid 和一个大小为 k 的数组 queries 。 找出一个大小为 k 的数组 answer ,且满足对于每个整数 queres[i] ,你从矩阵 左上角 单元格开始,重复以下过程&#xf…

2022年了,你还没搞清楚箭头函数与普通函数的区别嘛?

目录 1.箭头函数简介 2.箭头函数与普通函数的区别 A.声明方式不同,匿名函数 B.this指向不同 C.箭头函数的this永远不会变,call、apply、bind也无法改变 D.箭头函数没有原型prototype E.箭头函数不能当成一个构造函数 F.箭头函数没有自己的argume…

javaSE(数据类型、运算、逻辑控制、方法)

1.初识Java JDK、JRE、JVM之间的关系? JDK(Java Development Kit):Java开发工具包,提供给Java程序员使用,包含了JRE,同时还包含了编译器javac与自带的调试工具Jconsole、jstack等。 JRE(Java Runtime Environment):Java运行时环…

LeetCode 1775. 通过最少操作次数使数组的和相等 --双指针

通过最少操作次数使数组的和相等 中等 174 相关企业 给你两个长度可能不等的整数数组 nums1 和 nums2 。两个数组中的所有值都在 1 到 6 之间(包含 1 和 6)。 每次操作中,你可以选择 任意 数组中的任意一个整数,将它变成 1 到 6 …

Android9.0以上系统安装Edxposed

说明:仅供学习使用,请勿用于非法用途,若有侵权,请联系博主删除 作者:zhu6201976 一、背景说明 Android9.0以前,Xposed框架可通过apk进行快速安装,github地址: GitHub - rovo89/Xpos…

CRACK:CAD Exchanger SDK 3.15.0/MAC/WIN/LINUX/Android

CAD Exchanger SDK用于读取、写入和可视化 3D CAD 文件的软件库 通过访问 CAD 和 BIM 数据,快速轻松地丰富您的 Web、服务器或桌面应用程序。Ω578867473 使用 CATIA、SOLIDWORKS、Creo、STEP、JT、IFC 以及来自 C、Python、C#、Java 和 JavaScript 的更多格式。 适…

人民日报强烈推荐的13本证书,含金量都很高!

人民日报每年都会推荐一些当代最具含金量的证书,并建议大学生在大学期间的时候着手准备,为毕业后的简历添加色彩。 本次,人民日报推荐的证书主要有下列13种: 01 CPA(注册会计师) 含金量:★★…

博客管理系统

大致思路 1. 引入的依赖 数据库 Maven Repository: mysql mysql-connector-java 5.1.47 (mvnrepository.com) <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mys…

centos7用容器搭建svn仓库和管理页面

文章目录安装docker拉取 svn 仓库管理镜像创建仓库使用仓库安装docker 安装 docker 服务 yum install -y docker 修改 docker 服务配置&#xff0c;添加镜像拉取加速路径 vim /etc/docker/daemon.json javascript {"registry-mirrors": ["http://f1361db2.m.da…

【网页期末作业】基于HTML学校教育网页项目的设计与实现

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…