iOS 查看.ipa文件組成(占用大小)

iOS打包出來(lái)的.ipa文件解壓之后,得到Payload文件夾,右鍵顯示包內(nèi)容得到包里面的內(nèi)容,但是無(wú)法看到可執(zhí)行文件的組成內(nèi)容及所占大小。

查看.ipa中的文件組成及所占大小。

QQ20190504-195217@2x.png

1.生成LinkMap,更改配置。在Target的Build Settings中更改Write Link Map File 為 Yes,這樣就可以生成Link Map文件了,但是這個(gè)文件在哪呢。通過(guò)修改Build Settings的Path To Link Map可以指定LinkMap文件的生成目錄,默認(rèn)是生成在Build文件夾下。

2.編譯后得到LinkMap.txt文件。編譯成功后在路徑下得到/Users/xxxx/Library/Developer/Xcode/DerivedData/HelloWorld-fitgtiqfrissytdwtvkxxhkhpsfq/Build/Intermediates.noindex/HelloWorld.build/Debug-iphonesimulator/HelloWorld.build/HelloWorld-LinkMap-normal-x86_64.txt文件。

QQ20190504-182120@2x.png

QQ20190504-194915@2x.png
  • LinkMap文件格式
# Path
# Arch: x86_64
# Object files:
# Sections:
# Symbols:
# Dead Stripped Symbols:

一個(gè)完整的LinkMap文件是分為這幾塊的,以#為分隔。

# Path: /Users/xxxx/Library/Developer/Xcode/DerivedData/HelloWorld-fitgtiqfrissytdwtvkxxhkhpsfq/Build/Products/Debug-iphonesimulator/HelloWorld.app/HelloWorld

Path記錄的是這個(gè)LinkMap對(duì)應(yīng)的安裝包的地址。

# Arch: x86_64

Arch指的是這個(gè)LinkMap對(duì)應(yīng)的架構(gòu)。

# Object files:
[  0] linker synthesized
[  1] /Users/xxxx/Library/Developer/Xcode/DerivedData/HelloWorld-fitgtiqfrissytdwtvkxxhkhpsfq/Build/Intermediates.noindex/HelloWorld.build/Debug-iphonesimulator/HelloWorld.build/HelloWorld.app-Simulated.xcent
[  2] /Users/xxxx/Library/Developer/Xcode/DerivedData/HelloWorld-fitgtiqfrissytdwtvkxxhkhpsfq/Build/Intermediates.noindex/HelloWorld.build/Debug-iphonesimulator/HelloWorld.build/Objects-normal/x86_64/ViewController.o
[  3] /Users/xxxx/Library/Developer/Xcode/DerivedData/HelloWorld-fitgtiqfrissytdwtvkxxhkhpsfq/Build/Intermediates.noindex/HelloWorld.build/Debug-iphonesimulator/HelloWorld.build/Objects-normal/x86_64/main.o
[  4] /Users/xxxx/Library/Developer/Xcode/DerivedData/HelloWorld-fitgtiqfrissytdwtvkxxhkhpsfq/Build/Intermediates.noindex/HelloWorld.build/Debug-iphonesimulator/HelloWorld.build/Objects-normal/x86_64/AppDelegate.o
[  5] /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphonesimulator.a(arclite.o)
[  6] /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.4.sdk/System/Library/Frameworks//Foundation.framework/Foundation.tbd
[  7] /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.4.sdk/usr/lib/libobjc.tbd
[  8] /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.4.sdk/usr/lib/libSystem.tbd
[  9] /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.4.sdk/System/Library/Frameworks//CoreFoundation.framework/CoreFoundation.tbd
[ 10] /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.4.sdk/System/Library/Frameworks//UIKit.framework/UIKit.tbd

Object files是編譯后生成的文件列表,比如這個(gè)程序class都編譯成了.o文件,像我們比較熟悉的AppDelegate.o文件等等。還有引進(jìn)來(lái)的幾個(gè)庫(kù),比如UIKit.tbd。

# Sections:
# Address   Size        Segment Section
0x100001910 0x00001AD0  __TEXT  __text
0x1000033E0 0x00000120  __TEXT  __stubs
0x100003500 0x000001F0  __TEXT  __stub_helper
0x1000036F0 0x00000BA2  __TEXT  __objc_methname
0x100004292 0x00000065  __TEXT  __objc_classname
0x1000042F7 0x0000087C  __TEXT  __objc_methtype
0x100004B73 0x0000024B  __TEXT  __cstring
0x100004DC0 0x00000008  __TEXT  __const
0x100004DC8 0x00000178  __TEXT  __entitlements
0x100004F40 0x000000B4  __TEXT  __unwind_info
0x100005000 0x00000078  __DATA  __got
0x100005078 0x00000010  __DATA  __nl_symbol_ptr
0x100005088 0x00000180  __DATA  __la_symbol_ptr
0x100005208 0x00000010  __DATA  __objc_classlist
0x100005218 0x00000008  __DATA  __objc_nlclslist
0x100005220 0x00000018  __DATA  __objc_protolist
0x100005238 0x00000008  __DATA  __objc_imageinfo
0x100005240 0x00000CF8  __DATA  __objc_const
0x100005F38 0x000000B8  __DATA  __objc_selrefs
0x100005FF0 0x00000008  __DATA  __objc_protorefs
0x100005FF8 0x00000008  __DATA  __objc_classrefs
0x100006000 0x00000008  __DATA  __objc_superrefs
0x100006008 0x00000008  __DATA  __objc_ivar
0x100006010 0x000000F0  __DATA  __objc_data
0x100006100 0x00000160  __DATA  __data
0x100006260 0x00000180  __DATA  __bss

Section是各種數(shù)據(jù)類型所在的內(nèi)存空間,Section主要分為兩大類,__Text和__DATA。__Text指的是程序代碼,__DATA指的是已經(jīng)初始化的變量等。
具體分類如下表所示。

以下是__TEXT段的section

__text 主程序代碼

stubs 和stub_helper 用于動(dòng)態(tài)鏈接庫(kù)的stub

__cstring c語(yǔ)言字符串

__const const修飾的常量

__objc_methname objc的方法名稱

__objc_methtype objc方法類型

__objc_classname objc類方法

以下是__DATA段的section

__objc_ivars objc類的實(shí)例變量

__objc_classlist objc類列表

__objc_protolist objc協(xié)議列表

__objc_imageinfo objc鏡像信息

__objc_const objc常量

__objc_selfrefs objc自引用(self)

__objc_protorefs objc協(xié)議引用

__objc_superrefs objc超類引用

__cfstring 使用Core Foundation字符串

__bss BSS

每個(gè)Section前面的兩個(gè)16進(jìn)制的數(shù)字代表的就是這個(gè)Section相對(duì)于安裝包初始內(nèi)存的偏移和這個(gè)Section的大小。比如:

0x100001910 0x00001AD0  __TEXT  __text

__text這個(gè)Section的偏移地址是0x100001910,這塊的大小是0x00001AD0,也就是6864個(gè)字節(jié)。

# Symbols:
# Address   Size        File  Name
0x100001910 0x00000040  [  2] -[ViewController viewDidLoad]
0x100001950 0x0000003C  [  2] -[ViewController didReceiveMemoryWarning]
0x100001990 0x00000090  [  3] _main
0x100001A20 0x00000080  [  4] -[AppDelegate application:didFinishLaunchingWithOptions:]
0x100001AA0 0x00000040  [  4] -[AppDelegate applicationWillResignActive:]
0x100001AE0 0x00000040  [  4] -[AppDelegate applicationDidEnterBackground:]
0x100001B20 0x00000040  [  4] -[AppDelegate applicationWillEnterForeground:]
0x100001B60 0x00000040  [  4] -[AppDelegate applicationDidBecomeActive:]
0x100001BA0 0x00000040  [  4] -[AppDelegate applicationWillTerminate:]
0x100001BE0 0x00000020  [  4] -[AppDelegate window]
0x100001C00 0x00000040  [  4] -[AppDelegate setWindow:]
0x100001C40 0x00000033  [  4] -[AppDelegate .cxx_destruct]

iOS開(kāi)發(fā)的同學(xué)對(duì)Symbols這個(gè)單詞肯定不陌生,什么Crash要有對(duì)應(yīng)的符號(hào)表,編譯的時(shí)候經(jīng)常保持找不到Symbols等。Symbols簡(jiǎn)單來(lái)說(shuō)就是類名,變量名,方法名等等符號(hào)。所以這一塊也詳細(xì)列出了這個(gè)安裝包內(nèi)各個(gè)方法所占的內(nèi)存大小。
這一塊太多了,我只列出一小部分,這塊同樣有四列,一二列和Sections的情況一樣,分別是偏移地址和大小。第四列是方法的符號(hào),類名+方法名。第三列是文件序號(hào),這個(gè)序號(hào)是哪里來(lái)的的,就是前面提到的Object files里文件的序號(hào),比如這里viewDidLoad的序號(hào)是2,去Object files去找序號(hào)是2的文件。

[  2] /Users/xxxx/Library/Developer/Xcode/DerivedData/HelloWorld-fitgtiqfrissytdwtvkxxhkhpsfq/Build/Intermediates.noindex/HelloWorld.build/Debug-iphonesimulator/HelloWorld.build/Objects-normal/x86_64/ViewController.o

也就是說(shuō)這個(gè)方法來(lái)自ViewController.o這個(gè)文件。
通過(guò)這種對(duì)應(yīng)關(guān)系,我可以知道一個(gè).o文件里有多少方法被編譯進(jìn)了安裝包,每個(gè)方法所占的體積,加起來(lái)我就知道每個(gè).o文件的大小了。后面的程序也就是把這個(gè)過(guò)程給自動(dòng)化了。

# Dead Stripped Symbols:
#           Size        File  Name
<<dead>>    0x00000018  [  2] CIE
<<dead>>    0x00000018  [  3] CIE
<<dead>>    0x00000006  [  4] literal string: class
<<dead>>    0x00000008  [  4] literal string: v16@0:8
<<dead>>    0x00000018  [  4] CIE
<<dead>>    0x0000000F  [  5] literal string: isKindOfClass:
<<dead>>    0x00000005  [  5] literal string: self
<<dead>>    0x00000008  [  5] literal string: release
<<dead>>    0x0000000E  [  5] literal string: v32@0:8@16@24
<<dead>>    0x00000018  [  5] CIE

最后還有一部分是沒(méi)用的符號(hào),這部分我也不知道是怎么產(chǎn)生的,但可以肯定的是這部分不應(yīng)該太大。

3.自動(dòng)分析:通過(guò)前面對(duì)LinkMap文件格式的解析,我們知道在LinkMap里,我們可以知道每個(gè)文件所占的體積大小,并且可以通過(guò)文件的前綴,知道文件所屬的動(dòng)態(tài)庫(kù),這樣也就可以知道動(dòng)態(tài)庫(kù)的大小。只是這個(gè)過(guò)程太過(guò)繁瑣,所以我們?nèi)グ阉詣?dòng)化了。項(xiàng)目開(kāi)源地址:LinkMapParser

?  LinkMapParser-master python --version
Python 2.7.10
  • 該工具支持分析一個(gè)link map文件和比較兩個(gè)link map文件,進(jìn)入下載的開(kāi)源項(xiàng)目LinkMapParser目錄,運(yùn)行的命令分別為:
python parselinkmap.py /Users/xxxx/Library/Developer/Xcode/DerivedData/HelloWorld-fitgtiqfrissytdwtvkxxhkhpsfq/Build/Intermediates.noindex/HelloWorld.build/Debug-iphonesimulator/HelloWorld.build/HelloWorld-LinkMap-normal-x86_64.txt
QQ20190504-191712@2x.png
python parselinkmap.py /Users/xxxx/Library/Developer/Xcode/DerivedData/HelloWorld-fitgtiqfrissytdwtvkxxhkhpsfq/Build/Intermediates.noindex/HelloWorld.build/Debug-iphonesimulator/HelloWorld.build/HelloWorld-LinkMap-normal-x86_64.txt /Users/xxxx/Library/Developer/Xcode/DerivedData/AddChildViewController-fmbyhwgpcjsxuzgomqidebjtmwnx/Build/Intermediates.noindex/AddChildViewController.build/Debug-iphonesimulator/AddChildViewController.build/AddChildViewController-LinkMap-normal-x86_64.txt
QQ20190504-192728@2x.png
QQ20190504-193508@2x.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容