clang -rewrite-objc main.m
将obj文件重写为 c, c++文件前端
clang -Xclang -ast-dump -fsyntax-only main.m
生成文件生成树ios
clang -Xclang -dump-tokens main.m
这里会把代码切成一个个 Token,好比大小括号,等于号还有字符串等c++
根据一个简单的例子来观察是如何进行编译的objective-c
#import <Foundation/Foundation.h>
#define DEFINEEight 8
int main(){
@autoreleasepool {
int eight = DEFINEEight;
int six = 6;
NSString* site = [[NSString alloc] initWithUTF8String:"starming"];
int rank = eight + six;
NSLog(@"%@ rank %d", site, rank);
}
return 0;
}
复制代码
在命令行编译shell
xcrun -sdk iphoneos clang -arch armv7 -F Foundation -fobjc-arc -c main.m -o main.o
xcrun -sdk iphoneos clang main.o -arch armv7 -fobjc-arc -framework Foundation -o main
# 这样还无法看清clang的所有过程,能够经过-E查看clang在预处理处理这步作了什么。
clang -E main.m
# 执行完后能够看到文件
# 1 "/System/Library/Frameworks/Foundation.framework/Headers/FoundationLegacySwiftCompatibility.h" 1 3
# 185 "/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h" 2 3
# 2 "main.m" 2
int main(){
@autoreleasepool {
int eight = 8;
int six = 6;
NSString* site = [[NSString alloc] initWithUTF8String:"starming"];
int rank = eight + six;
NSLog(@"%@ rank %d", site, rank);
}
return 0;
}
# 这个过程的处理包括宏的替换,头文件的导入,以及相似#if的处理。预处理完成后就会进行词法分析,这里会把代码切成一个个 Token,好比大小括号,等于号还有字符串等。
clang -fmodules -fsyntax-only -Xclang -dump-tokens main.m
# 而后是语法分析,验证语法是否正确,而后将全部节点组成抽象语法树 AST 。
clang -fmodules -fsyntax-only -Xclang -ast-dump main.m
# 完成这些步骤后就能够开始IR中间代码的生成了,CodeGen 会负责将语法树自顶向下遍历逐步翻译成 LLVM IR,IR 是编译过程的前端的输出后端的输入。
clang -S -fobjc-arc -emit-llvm main.m -o main.ll
# 这里 LLVM 会去作些优化工做,在 Xcode 的编译设置里也能够设置优化级别-01,-03,-0s,还能够写些本身的 Pass。
# Pass 是 LLVM 优化工做的一个节点,一个节点作些事,一块儿加起来就构成了 LLVM 完整的优化和转化。
# 若是开启了 bitcode 苹果会作进一步的优化,有新的后端架构仍是能够用这份优化过的 bitcode 去生成。
clang -emit-llvm -c main.m -o main.bc
# 生成汇编
clang -S -fobjc-arc main.m -o main.s
# 生成目标文件
clang -fmodules -c main.m -o main.o
# 生成可执行文件,这样就可以执行看到输出结果
clang main.o -o main
# 执行
./main
# 输出
starming rank 14
复制代码
下面是完整步骤后端
在 Xcode 中查看 clang 编译 .m 文件的过程xcode
使用编译 Masonry 框架的 MASCompositeConstraint.m 为例, 首先对任务进行描述bash
CompileC /Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/Objects-normal/x86_64/MASCompositeConstraint.o
Masonry/Masonry/MASCompositeConstraint.m normal x86_64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
复制代码
更新工做路径,同时设置 PATHsession
cd /Users/lanya/Desktop/Neuer_iOS/Pods
export LANG=en_US.US-ASCII
export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
复制代码
接下来是实际的编译命令架构
先介绍一下 clang 的命令参数,再看👇的编译命令会更容易理解
clang 命令参数
-x 编译语言好比objective-c
-arch 编译的架构,好比arm7
-f 以-f开头的。
-W 以-W开头的,能够经过这些定制编译警告
-D 以-D开头的,指的是预编译宏,经过这些宏能够实现条件编译
-iPhoneSimulator11.1.sdk 编译采用的iOS SDK版本
-I 把编译信息写入指定的辅助文件
-F 须要的Framework
-c 标识符指明须要运行预处理器,语法分析,类型检查,LLVM生成优化以及汇编代码生成.o文件
-o 编译结果
复制代码
具体的编译过程
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -x objective-c -arch x86_64 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -std=gnu11 -fobjc-arc -fmodules -gmodules -fmodules-cache-path=/Users/lanya/Library/Developer/Xcode/DerivedData/ModuleCache -fmodules-prune-interval=86400 -fmodules-prune-after=345600 -fbuild-session-file=/Users/lanya/Library/Developer/Xcode/DerivedData/ModuleCache/Session.modulevalidation -fmodules-validate-once-per-build-session -Wnon-modular-include-in-framework-module -Werror=non-modular-include-in-framework-module -fmodule-name=Masonry -fapplication-extension -Wno-trigraphs -fpascal-strings -O0 -fno-common -Wno-missing-field-initializers -Wno-missing-prototypes -Werror=return-type -Wdocumentation -Wunreachable-code -Wno-implicit-atomic-properties -Werror=deprecated-objc-isa-usage -Werror=objc-root-class -Wno-arc-repeated-use-of-weak -Wduplicate-method-match -Wno-missing-braces -Wparentheses -Wswitch -Wunused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wempty-body -Wuninitialized -Wconditional-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wconstant-conversion -Wint-conversion -Wbool-conversion -Wenum-conversion -Wno-float-conversion -Wnon-literal-null-conversion -Wobjc-literal-conversion -Wshorten-64-to-32 -Wpointer-sign -Wno-newline-eof -Wno-selector -Wno-strict-selector-match -Wundeclared-selector -Wno-deprecated-implementations -DPOD_CONFIGURATION_DEBUG=1 -DDEBUG=1 -DCOCOAPODS=1 -DOBJC_OLD_DISPATCH_PROTOTYPES=0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.2.sdk -fasm-blocks -fstrict-aliasing -Wprotocol -Wdeprecated-declarations -mios-simulator-version-min=8.0 -g -Wno-sign-conversion -Winfinite-recursion -Wcomma -Wblock-capture-autoreleasing -Wstrict-prototypes -Wunguarded-availability -fobjc-abi-version=2 -fobjc-legacy-dispatch -index-store-path /Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Index/DataStore -iquote /Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/Masonry-generated-files.hmap -I/Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/Masonry-own-target-headers.hmap -I/Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/Masonry-all-non-framework-target-headers.hmap -ivfsoverlay /Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/all-product-headers.yaml -iquote /Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/Masonry-project-headers.hmap -I/Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Products/Debug-iphonesimulator/Masonry/include -I/Users/lanya/Desktop/Neuer_iOS/Pods/Headers/Private -I/Users/lanya/Desktop/Neuer_iOS/Pods/Headers/Public -I/Users/lanya/Desktop/Neuer_iOS/Pods/Headers/Public/PgyUpdate -I/Users/lanya/Desktop/Neuer_iOS/Pods/Headers/Public/Pgyer -I/Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/DerivedSources/x86_64 -I/Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/DerivedSources -F/Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Products/Debug-iphonesimulator/Masonry -include /Users/lanya/Desktop/Neuer_iOS/Pods/Target\ Support\ Files/Masonry/Masonry-prefix.pch -MMD -MT dependencies -MF /Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/Objects-normal/x86_64/MASCompositeConstraint.d --serialize-diagnostics /Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/Objects-normal/x86_64/MASCompositeConstraint.dia -c /Users/lanya/Desktop/Neuer_iOS/Pods/Masonry/Masonry/MASCompositeConstraint.m -o /Users/lanya/Library/Developer/Xcode/DerivedData/NEUer-bjvoyplxzoxgkpgkiodfvurkgzwn/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/Masonry.build/Objects-normal/x86_64/MASCompositeConstraint.o
复制代码
编译完第三方库后会进行构建咱们程序的 target
Create product structure
Process product packaging
Run custom shell script 'Check Pods Manifest.lock'
Compile ... 各个项目中的.m文件
Link /Users/... 路径
Copy ... 静态文件
Compile asset catalogs
Compile Storyboard file ...
Process info.plist
Link Storyboards
Run custom shell script 'Embed Pods Frameworks'
Run custom shell script 'Copy Pods Resources'
...
Touch NEUer.app
Sign NEUer.app
复制代码
Target 在 Build 过程的控制
Build Phases
Bulid Rules
Bulid Settings
pbxproj 工程文件
* build 过程控制的这些设置都会被保存在工程文件 .pbxproj 里。在这个文件中能够找 rootObject 的 ID 值
* 而后根据这个 ID 找到 main 工程的定义。
```objective-c
/* Begin PBXProject section */
2EC5E1AA1E7814B200BAB0EF /* Project object */ = {
isa = PBXProject;
......
/* End PBXProject section */
```
* 在 targets 里会指向各个 taget 的定义
```objective-c
targets = (
2EC5E1B11E7814B200BAB0EF /* EWork */,
);
// 根据 2EC5E1B11E7814B200BAB0EF 能够找到具体各个的定义
/**
这个里面又有更多的 ID 能够获得更多的定义,其中 buildConfigurationList 指向了可用的配置项,包含 Debug 和 Release。能够看到还有 buildPhases,buildRules 和 dependencies 都可以经过这里索引找到更详细的定义。
*/
/* Begin PBXNativeTarget section */
2EC5E1B11E7814B200BAB0EF /* EWork */ = {
isa = PBXNativeTarget;
buildConfigurationList = 2EC5E1CC1E7814B200BAB0EF /* Build configuration list for PBXNativeTarget "EWork" */;
buildPhases = (
73F5AAE2AEC5EE766978C0E2 /* [CP] Check Pods Manifest.lock */,
2EC5E1AE1E7814B200BAB0EF /* Sources */,
2EC5E1AF1E7814B200BAB0EF /* Frameworks */,
2EC5E1B01E7814B200BAB0EF /* Resources */,
B42D03564A9A71BAD7183E61 /* [CP] Embed Pods Frameworks */,
4672989246AFA7B2776DFA56 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = EWork;
productName = EWork;
productReference = 2EC5E1B21E7814B200BAB0EF /* EWork.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
// 好比 XCConfigurationList
/* Begin XCConfigurationList section */
2EC5E1AD1E7814B200BAB0EF /* Build configuration list for PBXProject "EWork" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2EC5E1CA1E7814B200BAB0EF /* Debug */,
2EC5E1CB1E7814B200BAB0EF /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
2EC5E1CC1E7814B200BAB0EF /* Build configuration list for PBXNativeTarget "EWork" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2EC5E1CD1E7814B200BAB0EF /* Debug */,
2EC5E1CE1E7814B200BAB0EF /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
```
复制代码
编译后生成的二进制内容 Link Map File
LinkMapFile
首先来讲一说什么是 LinkMap
为何要使用 LinkMap
当一个中大型iOS项目在不断迭代更新的过程当中,代码量日渐壮大,须要重构和review的代码也愈来愈多,可一旦代码达到必定程度后变得不是那么可控,为了使得项目还能够持续可集成稳健的开发下去,缩小iOS安装包大小是必需要作的事情,一般会从压缩图片和音频文件开始,使用开发工具查找冗余不用的资源文件,这一阶段以后只能经过对代码的重构来达到可执行文件总体瘦身的效果。当从事参与的一个项目在不断迭代过程当中,App的安装包在不断变大,经过本身的shell脚本分析,多达几十万行,这时候很是有瘦身的必要,这其中包括了.h.m.mm.cpp.rss格式文件。观察项目中引入的Pods文件及相关第三方库,多达上百个库,这时候这样一个中大型App就涉及到应用瘦身的问题,如何才能有效解决代码不可控的问题,如何能提升项目中底层基础架构的稳定性及健壮性,相信LinkMap能给予咱们一些答案。
LinkMap 的构成
# Path: /Users/lanya/Library/Developer/Xcode/DerivedData/littleTest-fcueraakmygtmodagachcreqjbjw/Build/Products/Debug/littleTest
# Arch: x86_64
LinkMap服务的开启方式及文件目录
Xcode->Project->Build Settings-> Search map -> 设置 Write Link Map Files 选项为YES
(这里须要注意的是否是设置Pods.xcodeproj的LinkMap而是xxx-xxxxx.xcodeproj,其余项目也要去设置主工程的对应编译选项,以此类推~/Library/Developer/Xcode/DerivedData/xxx-xxx-fwtuexpkzxsfkjaootcqwizogrhf/Build/Intermediates/xx-xxx.build/Debug-iphonesimulator/xxx-xxx.build/xxx-xxx-LinkMap-normal-x86_64.txt
/Users/lanya/Library/Developer/Xcode/DerivedData/littleTest-fcueraakmygtmodagachcreqjbjw/Build/Intermediates.noindex/littleTest.build/Debug/littleTest.build/littleTest-LinkMap-normal-x86_64.txt
如今来讲一说 LinkMap 各部分的做用
App的完整的目标文件列表(#Object files): 这个部分的内容都是 .m 文件编译后的 .o 和须要 link 的 .a 文件。前面是文件编号,后面是文件路径。
# Object files:
[ 0] linker synthesized
[ 1] /Users/lanya/Library/Developer/Xcode/DerivedData/littleTest-fcueraakmygtmodagachcreqjbjw/Build/Intermediates.noindex/littleTest.build/Debug/littleTest.build/Objects-normal/x86_64/main.o
[ 2] /Users/lanya/Library/Developer/Xcode/DerivedData/littleTest-fcueraakmygtmodagachcreqjbjw/Build/Intermediates.noindex/littleTest.build/Debug/littleTest.build/Objects-normal/x86_64/Test.o
[ 3] /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks//Foundation.framework/Foundation.tbd
[ 4] /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/lib/libobjc.tbd
复制代码
App的段表(#Section):这里描述的是每一个 Section 在可执行文件中的位置和大小。每一个 Section 的 Segment 的类型分为 __TEXT 代码段和 __DATA 数据段两种。
# Sections:
# Address Size Segment Section
0x100000B10 0x000002D9 __TEXT __text
0x100000DEA 0x00000054 __TEXT __stubs
0x100000E40 0x0000009C __TEXT __stub_helper
0x100000EDC 0x0000006E __TEXT __objc_methname
0x100000F4A 0x0000003B __TEXT __cstring
0x100000F85 0x00000007 __TEXT __objc_classname
0x100000F8C 0x0000001D __TEXT __objc_methtype
0x100000FAC 0x00000048 __TEXT __unwind_info
0x100001000 0x00000010 __DATA __nl_symbol_ptr
0x100001010 0x00000070 __DATA __la_symbol_ptr
0x100001080 0x00000060 __DATA __cfstring
0x1000010E0 0x00000008 __DATA __objc_classlist
0x1000010E8 0x00000008 __DATA __objc_imageinfo
0x1000010F0 0x00000170 __DATA __objc_const
0x100001260 0x00000020 __DATA __objc_selrefs
0x100001280 0x00000008 __DATA __objc_classrefs
0x100001288 0x00000008 __DATA __objc_superrefs
0x100001290 0x00000010 __DATA __objc_ivar
0x1000012A0 0x00000050 __DATA __objc_data
复制代码
App中具体目标文件在对应的section中的位置和大小(#Symbols):Symbols 是对 Sections 进行了再划分。这里会描述全部的 methods,ivar 和字符串,及它们对应的地址,大小,文件编号信息。
# Symbols:
# Address Size File Name
0x100000B10 0x00000106 [ 1] _main
0x100000C20 0x000000A0 [ 2] -[Test init]
0x100000CC0 0x00000060 [ 2] -[Test setObject:]
0x100000D20 0x00000040 [ 2] -[Test obj]
0x100000D60 0x00000040 [ 2] -[Test setObj:]
0x100000DA0 0x00000049 [ 2] -[Test .cxx_destruct]
0x100000DEA 0x00000006 [ 3] _NSHomeDirectory
0x100000DF0 0x00000006 [ 3] _NSLog
0x100000DF6 0x00000006 [ 4] _objc_autoreleasePoolPop
0x100000DFC 0x00000006 [ 4] _objc_autoreleasePoolPush
0x100000E02 0x00000006 [ 4] _objc_autoreleaseReturnValue
0x100000E08 0x00000006 [ 4] _objc_destroyWeak
0x100000E0E 0x00000006 [ 4] _objc_loadWeakRetained
0x100000E14 0x00000006 [ 4] _objc_msgSend
0x100000E1A 0x00000006 [ 4] _objc_msgSendSuper2
0x100000E20 0x00000006 [ 4] _objc_release
0x100000E26 0x00000006 [ 4] _objc_retain
0x100000E2C 0x00000006 [ 4] _objc_retainAutoreleasedReturnValue
0x100000E32 0x00000006 [ 4] _objc_storeStrong
0x100000E38 0x00000006 [ 4] _objc_storeWeak
0x100000E40 0x00000010 [ 0] helper helper
0x100000E50 0x0000000A [ 3] _NSHomeDirectory
0x100000E5A 0x0000000A [ 3] _NSLog
0x100000E64 0x0000000A [ 4] _objc_autoreleasePoolPop
0x100000E6E 0x0000000A [ 4] _objc_autoreleasePoolPush
0x100000E78 0x0000000A [ 4] _objc_autoreleaseReturnValue
0x100000E82 0x0000000A [ 4] _objc_destroyWeak
0x100000E8C 0x0000000A [ 4] _objc_loadWeakRetained
0x100000E96 0x0000000A [ 4] _objc_msgSend
0x100000EA0 0x0000000A [ 4] _objc_msgSendSuper2
0x100000EAA 0x0000000A [ 4] _objc_release
0x100000EB4 0x0000000A [ 4] _objc_retain
0x100000EBE 0x0000000A [ 4] _objc_retainAutoreleasedReturnValue
0x100000EC8 0x0000000A [ 4] _objc_storeStrong
0x100000ED2 0x0000000A [ 4] _objc_storeWeak
0x100000EDC 0x00000006 [ 1] literal string: alloc
0x100000EE2 0x00000014 [ 1] literal string: initWithUTF8String:
0x100000EF6 0x00000020 [ 1] literal string: stringByAppendingPathComponent:
0x100000F16 0x00000005 [ 2] literal string: init
0x100000F1B 0x0000000B [ 2] literal string: setObject:
0x100000F26 0x0000000E [ 2] literal string: .cxx_destruct
0x100000F34 0x00000004 [ 2] literal string: obj
0x100000F38 0x00000008 [ 2] literal string: setObj:
0x100000F40 0x00000005 [ 2] literal string: obj_
0x100000F45 0x00000005 [ 2] literal string: _obj
0x100000F4A 0x00000009 [ 1] literal string: starming
0x100000F53 0x0000000B [ 1] literal string: %@ rank %d
0x100000F5E 0x00000013 [ 1] literal string: Documents/neuer.db
0x100000F71 0x00000003 [ 1] literal string: %@
0x100000F74 0x00000004 [ 2] literal string: obj
0x100000F78 0x0000000D [ 2] literal string: T@,W,N,V_obj
0x100000F85 0x00000005 [ 2] literal string: Test
0x100000F8A 0x00000002 [ 2] literal string:
0x100000F8C 0x00000008 [ 2] literal string: @16@0:8
0x100000F94 0x0000000B [ 2] literal string: v24@0:8@16
0x100000F9F 0x00000008 [ 2] literal string: v16@0:8
0x100000FA7 0x00000002 [ 2] literal string: @
0x100000FAC 0x00000048 [ 0] compact unwind info
0x100001000 0x00000008 [ 0] non-lazy-pointer-to-local: dyld_stub_binder
0x100001008 0x00000008 [ 0] non-lazy-pointer
0x100001010 0x00000008 [ 3] _NSHomeDirectory
0x100001018 0x00000008 [ 3] _NSLog
0x100001020 0x00000008 [ 4] _objc_autoreleasePoolPop
0x100001028 0x00000008 [ 4] _objc_autoreleasePoolPush
0x100001030 0x00000008 [ 4] _objc_autoreleaseReturnValue
0x100001038 0x00000008 [ 4] _objc_destroyWeak
0x100001040 0x00000008 [ 4] _objc_loadWeakRetained
0x100001048 0x00000008 [ 4] _objc_msgSend
0x100001050 0x00000008 [ 4] _objc_msgSendSuper2
0x100001058 0x00000008 [ 4] _objc_release
0x100001060 0x00000008 [ 4] _objc_retain
0x100001068 0x00000008 [ 4] _objc_retainAutoreleasedReturnValue
0x100001070 0x00000008 [ 4] _objc_storeStrong
0x100001078 0x00000008 [ 4] _objc_storeWeak
0x100001080 0x00000020 [ 1] CFString
0x1000010A0 0x00000020 [ 1] CFString
0x1000010C0 0x00000020 [ 1] CFString
0x1000010E0 0x00000008 [ 2] anon
0x1000010E8 0x00000008 [ 0] objc image info
0x1000010F0 0x00000048 [ 2] l_OBJC_METACLASS_RO_$_Test
0x100001138 0x00000080 [ 2] l_OBJC_$_INSTANCE_METHODS_Test
0x1000011B8 0x00000048 [ 2] l_OBJC_$_INSTANCE_VARIABLES_Test
0x100001200 0x00000018 [ 2] l_OBJC_$_PROP_LIST_Test
0x100001218 0x00000048 [ 2] l_OBJC_CLASS_RO_$_Test
0x100001260 0x00000008 [ 1] pointer-to-literal-cstring
0x100001268 0x00000008 [ 1] pointer-to-literal-cstring
0x100001270 0x00000008 [ 1] pointer-to-literal-cstring
0x100001278 0x00000008 [ 2] pointer-to-literal-cstring
0x100001280 0x00000008 [ 1] objc-class-ref
0x100001288 0x00000008 [ 2] anon
0x100001290 0x00000008 [ 2] _OBJC_IVAR_$_Test.obj_
0x100001298 0x00000008 [ 2] _OBJC_IVAR_$_Test._obj
0x1000012A0 0x00000028 [ 2] _OBJC_CLASS_$_Test
0x1000012C8 0x00000028 [ 2] _OBJC_METACLASS_$_Test
复制代码
dSYM
/Users/用户名/Library/Developer/Xcode/DerivedData/littleTest-fcueraakmygtmodagachcreqjbjw/Build/Products/Release
find /Applications/Xcode.app -name symbolicatecrash -type f
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash
Mach-O 文件
含义:Mach-O,是Mach object文件格式的缩写,是一种可执行文件、目标代码、共享程序库、动态加载代码和核心DUMP。是a.out格式的一种替代。Mach-O 提供更多的可扩展性和更快的符号表信息存取。Mach-O应用在基于Mach核心的系统上,目前NeXTSTEP、Darwin、Mac OS X(iPhone)都是使用这种可执行文件格式。
记录编译后的可执行文件,对象代码,共享库,动态加载代码和内存转储的文件格式。不一样于 xml 这样的文件,它只是二进制字节流,里面有不一样的包含元信息的数据块,好比字节顺序,cpu 类型,块大小等。文件内容是不能够修改的,由于在 .app 目录中有个 _CodeSignature 的目录,里面包含了程序代码的签名,这个签名的做用就是保证签名后 .app 里的文件,包括资源文件,Mach-O 文件都不可以更改。
Mach-O 的内容:
先看看描述这个文件的结构体
struct mach_header {
uint32_t magic;
cpu_type_t cputype;
cpu_subtype_t cpusubtype;
uint32_t filetype;
uint32_t ncmds;
uint32_t sizeofcmds;
uint32_t flags;
};
struct segment_command {
uint32_t cmd;
uint32_t cmdsize;
char segname[16];
uint32_t vmaddr;
uint32_t vmsize;
uint32_t fileoff;
uint32_t filesize;
vm_prot_t maxprot;
vm_prot_t initprot;
uint32_t nsects;
uint32_t flags;
};
复制代码
Mach-O 文件参考文章
dyld动态连接
参考文章: 深刻剖析iOS编译