iOS Link Map / 2019-05-14

由Xcode build产生的Link Map文件能比较直观的反映出程序各部分的文件大小情况,对于减少包体积很有帮助。

开启Link Map

Build Setting->Write Link Map File设置为YES。在Path to Link Map File中设置Link map文件的路径,默认为:

$(TARGET_TEMP_DIR)/$(PRODUCT_NAME)-LinkMap-$(CURRENT_VARIANT)-$(CURRENT_ARCH).txt

示例:

~/Library/Developer/Xcode/DerivedData/EaseAPIDemo-cqprnjddntshiocqosnzjwpwfbdz/Build/Intermediates.noindex/EaseAPIDemo.build/Debug-iphoneos/EaseAPIDemo.build/EaseAPIDemo-LinkMap-normal-arm64.txt

Link Map文件

Link Map就是文本文件,主要是用于分析每个文件代码段的大小,常量,静态字符串等信息。

Object files

最前面的部分是Object files,展示了参与编译的所有文件序号及路径(.o文件)。示例:

[2] ../test/Debug-iphonesimulator/EaseAPIDemo(TestUtils.o)
[3] ../test/Debug-iphonesimulator/EaseAPIDemo(TestCell.o)
[4] ../test/Debug-iphonesimulator/EaseAPIDemo(TestView.o)
***
[1222] ***Foundation.framework/Foundation
[1223] ***UIKit.framework/UIKit

前面是文件编号,引用的framework也一样会列出来。

Segment & section

接着是section表,是按照 mach-o 文件映射的Segment和section信息。

0x100006AE4	0x0005A5AC	__TEXT	__text
0x100061090	0x00000984	__TEXT	__stubs
0x100061A14	0x0000099C	__TEXT	__stub_helper
0x1000623B0	0x00001180	__TEXT	__const
0x100063530	0x00002B96	__TEXT	__objc_methname
0x1000660C6	0x000000D0	__TEXT	__objc_classname
0x100066196	0x00000CEC	__TEXT	__objc_methtype
0x100066E82	0x00013955	__TEXT	__cstring
0x10007A7D8	0x000010D2	__TEXT	__ustring
0x10007B8AC	0x000000A8	__TEXT	__gcc_except_tab
0x10007B954	0x000006A8	__TEXT	__unwind_info
0x10007C000	0x000003E0	__DATA	__got
0x10007C3E0	0x00000658	__DATA	__la_symbol_ptr
0x10007CA38	0x00000AE0	__DATA	__const
0x10007D518	0x00000E20	__DATA	__cfstring
0x10007E338	0x00000040	__DATA	__objc_classlist
0x10007E378	0x00000010	__DATA	__objc_nlclslist
0x10007E388	0x00000000	__DATA	__objc_catlist
0x10007E388	0x00000020	__DATA	__objc_protolist
0x10007E3A8	0x00000008	__DATA	__objc_imageinfo
0x10007E3B0	0x00003348	__DATA	__objc_const
0x1000816F8	0x00000940	__DATA	__objc_selrefs
0x100082038	0x00000008	__DATA	__objc_protorefs
0x100082040	0x00000178	__DATA	__objc_classrefs
0x1000821B8	0x00000018	__DATA	__objc_superrefs
0x1000821D0	0x00000064	__DATA	__objc_ivar
0x100082238	0x000002D0	__DATA	__objc_data
0x100082508	0x00001460	__DATA	__data
0x100083968	0x000026B0	__DATA	__bss
0x100086018	0x0000005C	__DATA	__common

其中__text是代码段,__data是数据段,__cfstring表示C字符常量section,__objc_classlist是全部Objective-C类列表,__objc_classrefs是引用到的Objective-C类列表(不包括通过反射引用的,这点特别注意)。

技巧:使用otool工具获得各自 __objc_classrefs和 __objc_classlist列表的地址去重后,得到的地址列表就是没有用到的类地址列表,在通过Link Map找到对应地址的无用类即可以删除无用的类。

otool -v -s __DATA __objc_classlist EaseAPIDemo_v7

符号表

接着是符号表,按照Object files表中的文件序号依次列出了所有的方法,地址和占用的空间大小,常量等。示例

0x100001E20	0x000000A0	[ 12] -[EaseAPIDemoInfo init]
0x100001EC0	0x00000240	[ 12] -[EaseAPIDemoInfo parameterInit]
0x100002100	0x00000190	[ 12] -[EaseAPIDemoInfo parameterValidation]
...
//如果是C语言的函数,直接显示函数名字,示例:
0x10470E254	0x00000006	[2063] _sqlite3_bind_blob
0x10470E25A	0x00000006	[2063] _sqlite3_bind_double
0x10470E260	0x00000006	[2063] _sqlite3_bind_int
0x10470E266	0x00000006	[2063] _sqlite3_bind_null
0x10470E26C	0x00000006	[2063] _sqlite3_bind_text16
0x10470E272	0x00000006	[2063] _sqlite3_close

根据以上信息即可分析每一个.o或者framework文件的内存占用大小,对于减小包大小有很大帮助。

其它文章

iOS Sign With Apple实践
iOS crash log分析实践
iOS APP灰度发布方案
iOS NSURLProtocol详解及使用陷阱
iOS Universal Links