iOS深入浅出
文章平均质量分 68
iOS底层深入探索
Holothurian
千里之行跬步起、江海之成小流积。有志始知蓬莱近、无为总觉咫尺远。
展开
-
13、动态库链接image not found问题本质
首先我们找到一个AFNetworking动态库: 将其咔咔咔改名为libAFNetworking.dylib、否则有坑$file AFNetworkingAFNetworking: Mach-O 64-bit dynamically linked shared library x86_64然后执行下通过 main 链接动态库的操作:脚本内容如下echo "----将 main.m 链接AFNetworking 编译为 main.o"clang -target x86_64-apple-m.原创 2021-09-09 11:05:34 · 1401 阅读 · 0 评论 -
11、静态库的理解
什么是静态库?静态库即静态链接库: 可以简单的看成一组目标文件的集合。即很多目标文件经过压缩打包后形成的文件。Windows下的 .lib、Linux和Mac下的 .a。Mac独有的 .framework缺点:浪费内存和磁盘空间,模块更新困难我们开始通过一个实际操作案例来理解静态库。从项目中我们拿出编译好的 libAFNetworking.a静态库文件、并且将其对应的 4.0 版本头文件都拿出来放在一起、同时创建一个main.m文件在其中引入AFNetworking内容。原创 2021-09-09 09:50:50 · 661 阅读 · 0 评论 -
12、Framework原理探索
我们先预先插眼 module 这个概念。比如我们在一个文件中每引入一个头文件的时候、这个头文件也会参与编译。在其他文件中引入这个头文件也会参与编译;module是clang为我们提供的一种专门用来解析头文件的格式module可以把我们的头文件预先编译成一个二进制、缓存到系统的一个目录中;那么再去引入这个头文件的时候就不需要再次编译了、直接获取这个二进制来使用就可。开始Framework之前、我们再引入Auto-Link概念、LC_LINKER_OPTION链接器的特性,Auto-L..原创 2021-09-09 09:27:57 · 305 阅读 · 0 评论 -
10、iOS编译命令小结
生成目标文件:目标文件包含了机器指令代码、数据、链接时需要的信息、符号表、调试信息、字符串表。我们需要记录一些clang指令:1、不指定target时、默认是 Mach-O 64-bit object x86_64:$ clang -x c -g -c main.c -o main.o-x: 指定编译文件语言类型-g: 生成调试信息-c: 生成目标文件,只运行preprocess,compile,assemble,不链接-o: 输出文件-isysroot: 使用的SDK路径-I<.原创 2021-09-09 09:08:57 · 399 阅读 · 0 评论 -
9、all_load与Objc与force_load
首先借助一个main.m文件、文件中虽然我们引入了StaticExample的头文件、但是我们并没有进行调用。#import <Foundation/Foundation.h>#import "StaticExample.h"int main(){ NSLog(@"test log ------");// StaticExample *a = [[StaticExample alloc]init];// NSLog(@"instance variable %@".原创 2021-09-08 16:49:20 · 313 阅读 · 0 评论 -
8、iOS strip 与 dead strip
strip在iOS中的作用是 剥掉目标文件中一些符号信息和调试信息,使文件变小。dead code strip : 死代码剥离、然后再去链接。那么strip在哪些地方不能起作用呢?动态库 不能strip全局符号、因为全局符号要作为导出符号。App中 间接符号表中的符号不能strip;那么App中 本地符号、全局符号都可以strip。静态库 = .o文件合集,存在重定位符号表,这个表中的数据也是不能strip的。所以 .o文件中能strip的是调试符号。因此我们在Build S..原创 2021-09-08 16:26:37 · 1299 阅读 · 0 评论 -
7、iOS Weak Symbol
Weak Symbol Weak Definition Symbol : 表示此符号为弱定义符号。如果静态链接器或动态链接器找到一个弱定义符号的实现,另一个实现将被忽略,弱定义也将被忽略。只能将合并部分中的符号标记为弱定义。 Weak Reference Symbol : 表示此未定义符号是弱引用。如果动态链接器找不到该符号的定义,则将其设置为0。链接器会将此符号设置弱链接标志。 弱定义符号我们这里有两种表现形式//weak def void weak_function(void) __.原创 2021-09-08 16:05:40 · 402 阅读 · 0 评论 -
6、导入导出符号与map文件
什么是导入导出符号呢?我们拿NSLog举例来看、NSLog存在于Foundation动态库中。FOUNDATION_EXPORT void NSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2) NS_NO_TAIL_CALL;如果使用了NSLog、则当前可执行文件则导入(import)了Foundation提供的NSLog符号。也就相当于Foundation导出了NSLog符号。(export)回到这样的案例中、我们来查看下符号信息/.原创 2021-09-08 15:50:10 · 893 阅读 · 0 评论 -
5、全局符号的理解
我们通过一个案例来理解全局符号的概念创建一个Framework项目名称为HSOneFramework、声明一个头文件HSOneFramework.h、#import <HSOneFramework/HSOneObject.h>创建一个HSOneObject类@interface HSOneObject : NSObject- (void)testOneObject;@end@implementation HSOneObjectvoid global_object(.原创 2021-09-08 15:26:23 · 851 阅读 · 0 评论 -
4、链接与符号表
生成目标文件的过程编译器(clang - cl) ----> 汇编器(llvm-as) —> .o文件链接器(llvm-ld)并没有被执行。目标文件不会包含Unix程序在被装载和执行时所必须的包含信息。怎么理解呢?通过我们之前定义的一些变量//未初始化全局变量int global_uninit_value;//初始化全局变量int global_init_value = 10;//将default_x 全局符号变成本地符号double default.原创 2021-09-08 15:12:37 · 447 阅读 · 0 评论 -
3、iOS Mach-O文件再解读
Mach-O文件概述:Mach-O(Mach Object)是macOS、iOS、iPadOS存储程序和库的文件格式。对应系统通过应用二进制接口(application binary interface),缩写为ABI来运行该格式的文件。Mach-O格式用来替代BSD(Berkeley Software Distribution:伯克利软件套件)Unix衍生系统的a.out格式。Mach-O文件格式保存在编译过程和链接过程中产生的机器代码和数据,从而为静态链接和动态链接的代码提供了单一文件格式。段.原创 2021-09-08 15:01:52 · 836 阅读 · 0 评论 -
2、iOS xcconfig文件配置
对于xcconfig文件、我们其实并不陌生、因为在使用cocoapods的时候、就已经在使用这个文件了、只是很多人不知道其中变量的含义。其中的变量以key-value的形式存放、对应到Build Settings中的各关键字。BUILD_SETTING_NAME = value变量的定义:按照命名规则,仅由大写字母、数字和下划线( _ )组成,原则上大写,也可以不大写。字符串可以是 “”,也可以是’’变量有三种特殊情况:在xcconfig中定义的变量与Build Settings.原创 2021-09-08 11:52:08 · 1734 阅读 · 0 评论 -
1、iOS 多环境配置
Project:包含了项目所有的代码,资源文件,所有信息。Target:对指定代码和资源文件的具体构建方式。Scheme:对指定Target的环境配置。当设置多个Target时、比如复制了一份Target工程:修改了Target名字、需要将对应的Info.plist文件名称改为一致、否则会报错找不到对应文件。需要修改Bungle ID 、这样才是不同的项目。当分别运行两个Target时、会出现两个App包。通过这种方式可以实现多环境配置当前两个Target操..原创 2021-09-08 11:35:43 · 303 阅读 · 0 评论 -
alloc拓展探索
回到最初的alloc创建对象HSPerson *p = [HSPerson alloc];//此处断点当我们运行案例断在断点处 点 Ctrl+Step into的时候 、我们首次调用alloc走的是 objc_alloc 方法、为什么会先先走 objc_alloc方法、经历如下流程呢?alloc —> objc_alloc --> callocAlloc --> objc_msgSend --> alloc在dyld加载阶段、我们晓得通过_dyld_objc_not原创 2021-06-09 00:46:46 · 315 阅读 · 0 评论 -
OC dyld750调用分析
一、准备工作工欲善其事,必先利其器。想要分析dyld调用原理、首先需要获取苹果源码。 1.获取苹果dyld-750.6源码调试备用、(经过多次编译试错、缺失部分头文件、苹果并未开源、去除dyld编译之外部分及修改部分不影响主体源码) 2.准备objc4-781可调式版本源码二、项目调试阶段创建个空工程DYLDExe:在ViewController中调用load函数并打断点。 开始阶段为第12条:_dyld_start、查看调用汇编信息、 3.根据函数信息走第1...原创 2021-06-06 14:48:10 · 894 阅读 · 0 评论 -
LLDB中的各种关键调试指令你都玩过吗?
LLDB源码中的调试指令命令解释器初始化时、先加载所有的命令字典、key为对应的命令、value为命令对应的对象#define REGISTER_COMMAND_OBJECT(NAME, CLASS) \ m_command_dict[NAME] = std::make_shared<CLASS>(*this); void CommandInterpreter::LoadCommandDictionary()原创 2021-06-05 14:42:05 · 295 阅读 · 0 评论 -
结构体内存对齐的原则
数据成员对齐规则:结构体(struct)和联合(union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int为4字节,则 要从4的整数倍地址开始存储)。结构体作为成员 :如果一个结构里有些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址 开始存储,(struct a里存有struct b,b 里有char,int ,double等元素,那b应该从8的整数倍.原创 2021-06-05 14:29:30 · 339 阅读 · 0 评论 -
实例方法和类方法动态解析
一、一个未实现的方法的调用经历如下过程方法 -- 消息 ---- 实例方法快速汇编查找IMP __objc_msgForward_impcache __objc_msgForward 实例方法 递归 -- 父类 --- NSObject 上述都没有找到方法实现、进入动态方法解析 二、如果一个方法只有声明、通过递归查找仍然没有找到实现、则进入动态方法解析、通过汇编调用可看到调用函数通过查找 __objc_msgSend_uncached 方法、查看arm64架...原创 2021-05-24 22:17:05 · 203 阅读 · 1 评论 -
一个信号量异步线程玩法
A、B并发执行后再执行C dispatch_queue_t queue = dispatch_queue_create("com.queue.semaphore", DISPATCH_QUEUE_CONCURRENT); dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); dispatch_async(queue, ^{ [NSThread sleepForTimeInterva...原创 2021-05-24 21:02:05 · 169 阅读 · 0 评论 -
dispatch_queue_create创建源码分析
1、创建队列的时候采用 dispatch_queue_create、底层内部源码为2、调用源码dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr) { return _dispatch_lane_create_with_target(label, attr, DISPATCH_TARGET_QUEUE_DEFAULT, true); }3、_dispatch_lane_c原创 2021-05-24 20:58:56 · 898 阅读 · 0 评论 -
OC中查看消息转发调用顺序
1、非源码工程中调用文件处添加一个方法extern void instrumentObjcMessageSends(BOOL);2、在想要查看消息转发调用顺序的地方开启这个方法、调用完毕后关掉instrumentObjcMessageSends(YES);[HSPerson walking];instrumentObjcMessageSends(NO);3、运行项目后、在电脑 /private/tmp/ 文件夹下会看到一个 msgSends- 开头的缓存文件、4、打开后就会看到消原创 2020-11-13 10:47:09 · 181 阅读 · 0 评论 -
如何查找KVO苹果官方文档
1、首先打开苹果开发地址https://developer.apple.com/2、翻到最下端点击 Documentation --- Read API documentationhttps://developer.apple.com/documentation/3、依旧翻到最下端点击 苹果的官方文档归档 Documentation Archivehttps://developer.apple.com/library/archive/navigation/4、在Documentati原创 2020-11-13 10:30:17 · 259 阅读 · 0 评论 -
查看OC文件底层编译常用方法
1、查看编译main的C++文件$ clang -rewrite-objc main.m -o main.cpp2、使用封装了clang的xcrun来查看带有UIKit系统其他动态库的文件模拟器 $ xcrun -sdk iphonesimulator clang -rewrite-objc ViewController.m 2.手机 $ xcrun -sdk iphoneos clang -rewrite-objc ViewController.m 查看底层编译文件原创 2020-11-06 09:44:33 · 259 阅读 · 0 评论 -
OC创建对象alloc流程
1.在项目中:创建对象 [HSPerson alloc]将调用NSObject底层的alloc函数创建对象 + (id)alloc { return _objc_rootAlloc(self);}2. alloc创建对象的时候会调用 _objc_rootAlloc函数// Base class implementation of +alloc. cls is not nil.// Calls [cls allocWithZone:nil].id_objc_rootAlloc(原创 2020-11-06 10:20:54 · 377 阅读 · 0 评论