LinkMap分析初窥
基础服务是为了开发人员更好的进行开发,LinkMap分析服务就是这样的存在
1.我们为什么要用LinkMap
当一个中大型iOS项目在不断迭代更新的过程中,代码量日渐壮大,需要重构和review的代码也越来越多,可一旦代码达到一定程度后变得不是那么可控,为了使得项目还可以持续可集成稳健的开发下去,缩小iOS安装包大小是必须要做的事情,通常会从压缩图片和音频文件开始,使用开发工具查找冗余不用的资源文件,这一阶段之后只能通过对代码的重构来达到可执行文件整体瘦身的效果。
当从事参与的一个项目在不断迭代过程中,App的安装包在不断变大,通过自己的shell脚本分析,多达几十万行,这时候非常有瘦身的必要,这其中包括了.h.m.mm.cpp.rss格式文件。观察项目中引入的Pods文件及相关第三方库,多达上百个库,这时候这样一个中大型App就涉及到应用瘦身的问题,如何才能有效解决代码不可控的问题,如何能提高项目中底层基础架构的稳定性及健壮性,相信LinkMap能给予我们一些答案。
2.LinkMap是什么
在iOS开发领域,LinkMap可能对初学者是一个陌生的名词,简而言之,LinkMap的输出是一个纯文本格式的文件,里面包含重要的编译信息及报错信息,这也是Apple用来分析你的应用的主要方式,通过这种方式可以发现应用中是否使用了私有库等不符合Apple提交应用规范的内容,但对于我们开发人员,LinkMap却是一个用于分析源码及查看Crash的有效途径。
3.LinkMap的构成
一份完整的LinkMap文件中包含了一下几个部分:
-
App的编译路径(#Path)
# Path: /Users/XXXXX/Library/Developer/Xcode/DerivedData/XXXXXXXXXXXX-fwtuexpkzxsfkjaootcqwizogrhf/Build/Products/Debug-iphonesimulator/XXXXX.app/XXXXXXX
-
App对应的架构(#Arch)
# Arch: x86_64
-
App的完整的目标文件列表(#Object files)
[1] /Users/XXXX/Library/Developer/Xcode/DerivedData/XXXXXXX-fwtuexpkzxsfkjaootcqwizogrhf/Build/Intermediates/XXXXX.build/Debug-iphonesimulator/XXXX.build/Objects-normal/x86_64/main.o
[2] /Users/XXXX/Library/Developer/Xcode/DerivedData/XXXX-fwtuexpkzxsfkjaootcqwizogrhf/Build/Products/Debug-iphonesimulator/libPods-XXXX-XXX-AFHTTPRequestOperationLogger.a(AFHTTPRequestOperationLogger.o)
[3] /Users/XX/Library/Developer/Xcode/DerivedData/XXXX-fwtuexpkzxsfkjaootcqwizogrhf/Build/Products/Debug-iphonesimulator/libPods-XXX-XXX-AFHTTPRequestOperationLogger.a(Pods-XXX-XXX-AFHTTPRequestOperationLogger-dummy.o)
[4] /Users/XX/Library/Developer/Xcode/DerivedData/XXXXXX-fwtuexpkzxsfkjaootcqwizogrhf/Build/Products/Debug-iphonesimulator/libPods-XXX-XXX-AFNetworking.a(AFHTTPClient.o)
...
-
App的段表(#Section)
段表标题中列举出了地址,大小,段类型以及段名称。
数据类型分为两种不同类型,一种是__TEXT,用于保存程序代码段经过编译后的机器码,另外一种是__DATA用于保存诸如全局变量或者局部变量。
段的区分更多,如__cstring为字符串常量,__bss表示未初始化的全局变量及局部静态变量,__const表示的是对应的不可变的变量。当然这一切的数据都是文件占用空间,并不是运行时的占用空间。# Address Size Segment Section 0x100001E80 0x0176F009 __TEXT __text 0x101770E8A 0x00002C58 __TEXT __stubs 0x101773AE4 0x00003288 __TEXT __stub_helper 0x101776D6C 0x000CD35C __TEXT __objc_methname 0x1018440D0 0x0011D09D __TEXT __cstring 0x10196116D 0x0001A327 __TEXT __objc_classname 0x10197B494 0x0001F64C __TEXT __objc_methtype 0x10199AAE0 0x00077720 __TEXT __const ...
-
App中具体目标文件在对应的section中的位置和大小(#Symbols)
0x100001E80 0x00000097 [ 1] _main 0x100001F20 0x000000B0 [ 2] +[AFHTTPRequestOperationLogger sharedLogger] 0x100001FD0 0x00000050 [ 2] ___44+[AFHTTPRequestOperationLogger sharedLogger]_block_invoke 0x100002020 0x00000010 [ 2] ___copy_helper_block_ 0x100002030 0x00000010 [ 2] ___destroy_helper_block_ 0x100002040 0x000000D0 [ 2] -[AFHTTPRequestOperationLogger init] 0x100002110 0x00000060 [ 2] -[AFHTTPRequestOperationLogger dealloc] ...
4.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(文件路径顺序基本一致,文件名会有所不同,自行查看)
5.LinkMap服务化
- 作为基础服务,我们直接看LinkMap文件有时候非常吃力,如果能够配合图形化的方式来分析应用,这样对于开发人员来说是大大的便利。
6.App瘦身及展望
App瘦身是目前天猫App需要解决的问题,不光是通过LinkMap分析源码,实际上还可以通过好几个维度进行瘦身,包括优化资源文件,优化编译选项,优化可执行文件,当然这些都可以继续深入细分。
苹果官方也带来一些App瘦身好消息,WWDC2015带来一个App Thining的App瘦身功能,这是Xcode7测试版本的功能之一,App Thining根据用户设备类别和屏幕分辨率的不同来定制不同的下载包,这样为用户很好的节省了存储空间,相信这也是一种很好的App瘦身方式。