前言
苹果对于提交审核的App中可执行文件有明确的大小限制,查看应用的可执行文件大小就需要利用LinkMap文件。

1.如何生成LinkMap文件
1).在工程的Build Setting中找到Write Link Map File并打开开关

2).在debug或者release下编译工程
3).先找到编译后的app文件,向上两级的Products同目录下有Intermediates.noindex文件夹,在该文件夹下能够找到名称为项目名-LinkMap-normal-x86_64.txt的文件(x86_64是架构,如果是真机,可能为arm64或者其他)

2.LinkMap有什么作用
LinKMap文件分为四个部分:
1:# Path:当前LinkMap编译的路径
1
| # Path: /Users/zhoumo1/Library/Developer/Xcode/DerivedData/LinkMapTest-brvtnqhfmtphzohebrymhqgdzhwp/Build/Products/Debug-iphonesimulator/LinkMapTest.app/LinkMapTest
|
2:# Arch:当前编译的系统架构
3:# Object files:编译的所有文件
1
2
3
4
5
6
7
8
9
| # Object files:
[ 0] linker synthesized
[ 1] /Users/zhoumo1/Library/Developer/Xcode/DerivedData/LinkMapTest-brvtnqhfmtphzohebrymhqgdzhwp/Build/Intermediates.noindex/LinkMapTest.build/Debug-iphonesimulator/LinkMapTest.build/LinkMapTest.app.xcent
[ 2] /Users/zhoumo1/Library/Developer/Xcode/DerivedData/LinkMapTest-brvtnqhfmtphzohebrymhqgdzhwp/Build/Intermediates.noindex/LinkMapTest.build/Debug-iphonesimulator/LinkMapTest.build/Objects-normal/x86_64/ViewController.o
[ 3] /Users/zhoumo1/Library/Developer/Xcode/DerivedData/LinkMapTest-brvtnqhfmtphzohebrymhqgdzhwp/Build/Intermediates.noindex/LinkMapTest.build/Debug-iphonesimulator/LinkMapTest.build/Objects-normal/x86_64/main.o
[ 4] /Users/zhoumo1/Library/Developer/Xcode/DerivedData/LinkMapTest-brvtnqhfmtphzohebrymhqgdzhwp/Build/Intermediates.noindex/LinkMapTest.build/Debug-iphonesimulator/LinkMapTest.build/Objects-normal/x86_64/AppDelegate.o
[ 5] /Users/zhoumo1/Downloads/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.2.sdk/System/Library/Frameworks//Foundation.framework/Foundation.tbd
[ 6] /Users/zhoumo1/Downloads/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.2.sdk/usr/lib/libobjc.tbd
[ 7] /Users/zhoumo1/Downloads/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.2.sdk/System/Library/Frameworks//UIKit.framework/UIKit.tbd
|
4:# Sections:
段表标题中列举出了地址,大小,段类型以及段名称。
数据类型分为两种不同类型,一种是TEXT,用于保存程序代码段经过编译后的机器码,另外一种是DATA用于保存诸如全局变量或者局部变量。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| # Sections:
# Address Size Segment Section
0x100001590 0x00000453 __TEXT __text
0x1000019E4 0x00000036 __TEXT __stubs
0x100001A1C 0x0000006A __TEXT __stub_helper
0x100001A86 0x00000A70 __TEXT __objc_methname
0x1000024F6 0x0000003C __TEXT __objc_classname
0x100002532 0x00000878 __TEXT __objc_methtype
0x100002DAA 0x0000007A __TEXT __cstring
0x100002E24 0x00000186 __TEXT __entitlements
0x100002FAC 0x00000048 __TEXT __unwind_info
0x100003000 0x00000010 __DATA __nl_symbol_ptr
0x100003010 0x00000048 __DATA __la_symbol_ptr
0x100003058 0x00000010 __DATA __objc_classlist
0x100003068 0x00000010 __DATA __objc_protolist
0x100003078 0x00000008 __DATA __objc_imageinfo
0x100003080 0x00000C48 __DATA __objc_const
0x100003CC8 0x00000030 __DATA __objc_selrefs
0x100003CF8 0x00000008 __DATA __objc_classrefs
0x100003D00 0x00000008 __DATA __objc_superrefs
0x100003D08 0x00000008 __DATA __objc_ivar
0x100003D10 0x000000A0 __DATA __objc_data
0x100003DB0 0x000000C0 __DATA __data
|
5:# Symbols:文件中每一个方法的大小
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # Symbols:
# Address Size File Name
0x100001590 0x00000040 [ 2] -[ViewController viewDidLoad]
0x1000015D0 0x00000050 [ 2] -[ViewController viewDidAppear:]
0x100001620 0x00000050 [ 2] -[ViewController viewWillAppear:]
0x100001670 0x00000050 [ 2] -[ViewController viewDidDisappear:]
0x1000016C0 0x0000003C [ 2] -[ViewController didReceiveMemoryWarning]
0x100001700 0x00000090 [ 3] _main
0x100001790 0x00000080 [ 4] -[AppDelegate application:didFinishLaunchingWithOptions:]
0x100001810 0x00000040 [ 4] -[AppDelegate applicationWillResignActive:]
0x100001850 0x00000040 [ 4] -[AppDelegate applicationDidEnterBackground:]
0x100001890 0x00000040 [ 4] -[AppDelegate applicationWillEnterForeground:]
0x1000018D0 0x00000040 [ 4] -[AppDelegate applicationDidBecomeActive:]
0x100001910 0x00000040 [ 4] -[AppDelegate applicationWillTerminate:]
0x100001950 0x00000020 [ 4] -[AppDelegate window]
0x100001970 0x00000040 [ 4] -[AppDelegate setWindow:]
0x1000019B0 0x00000033 [ 4] -[AppDelegate .cxx_destruct]
···
|
3.如何减少库大小
除了第三方的库以外,我们还能对自己的代码做些什么?
1)注释或删除空方法和没有调用的方法
如上文分析,类中存在的方法就会被计算大小,无论是否调用。所以可以删除类中 如:
1
2
3
4
5
6
| - (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
}
- (void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
}
|
多加了两个空方法的大小对比如下,虽然空方法占用的很少,但是如果数量比较多还是很可观。

2)比较去重
分析过滤项目中的重复代码。通过整合减少代码量。
介绍一种去重的方法,使用PMD去重:
1.下载:https://sourceforge.net/projects/pmd/files/pmd/
2.cd 到bin目录中
3.在终端输入
1
| ./run.sh cpd --language ObjectiveC --minimum-tokens 100 --files /Users/zhoumo1/Desktop/LinkMap/LinkMapTest/LinkMapTest > /Users/zhoumo1/Desktop/check.txt
|
4.查看结果~完美
3)升级最低版本||重构
这没什么好说的,iOS9已经支持到500M,如果实在不能删减,升级最低支持版本是最有效的。
重构风险较大,并且重构后也不一定会小很多,不支持。
4.LinkMap比对
为了方便查看做了以上减少工作后的结果如何,于是写了一个简单的Mac应用,主要功能是对比两份LinkMap文件。
git地址:https://github.com/zhoumo199163/compareLinkMap
如果觉得对你有用,欢迎star~