iOS 15 如何讓 App 啟動(dòng)更快?

部署在 macOS 12 或 iOS 15 及更高版本操作系統(tǒng)上的所有程序及 dylibs現(xiàn)在都使用鏈?zhǔn)叫迯?fù)格式。這種格式使用不同的加載命令和 LINKEDIT 數(shù)據(jù),不能在低版本的操作系統(tǒng)上運(yùn)行或加載。

% xcrun dyldinfo -rebase -bind Snapchat.app/Snapchatrebase information (from compressed dyld info):segment section address type__DATA __got 0x10748C0C8 pointer...bind information:segment section address type addend dylib symbol__DATA __const 0x107595A70 pointer 0 libswiftCore_$sSHMp


一種新的格式
% otool -l iOS14Example.app/iOS14Example | grep LC_DYLDcmd LC_DYLD_INFO_ONLY% otool -l iOS15Example.app/iOS15Example | grep LC_DYLDcmd LC_DYLD_CHAINED_FIXUPScmd LC_DYLD_EXPORTS_TRIE

let bytes = (try! Data(contentsOf: url) as NSData).bytesbytes.processLoadComands { load_command, pointer inif load_command.cmd == LC_DYLD_EXPORTS_TRIE {let dataCommand = pointer.load(as: linkedit_data_command.self)bytes.advanced(by: Int(dataCommand.dataoff)).readExportTrie()}}extension UnsafeRawPointer {func readExportTrie() {var frontier = readNode(name: "")guard !frontier.isEmpty else { return }repeat {let (prefix, offset) = frontier.removeFirst()let children = advanced(by: Int(offset)).readNode(name: prefix)for (suffix, offset) in children {frontier.append((prefix + suffix, offset))}} while !frontier.isEmpty}// Returns an array of child nodes and their offsetfunc readNode(name: String) -> [(String, UInt)] {guard load(as: UInt8.self) == 0 else {// This is a terminal nodeprint("symbol name \(name)")return []}let numberOfBranches = UInt(advanced(by: 1).load(as: UInt8.self))var mutablePointer = self.advanced(by: 2)var result = [(String, UInt)]()for _ in 0..<numberOfBranches {result.append((mutablePointer.readNullTerminatedString(),mutablePointer.readULEB()))}return result}}

鏈

struct dyld_chained_ptr_64_rebase{uint64_t target : 36,high8 : 8,reserved : 7, // 0snext : 12,bind : 1; // Always 0 for a rebase};


% xcrun dyldinfo -rebase Snapchat.app/Snapchat > rebases% ruby -e 'puts IO.read("rebases").split("\n").drop(2).map { |a| a.split(" ")[2].to_i(16) / 16384 }.uniq.count'1554% xcrun dyldinfo -bind Snapchat.app/Snapchat > binds450

減少動(dòng)態(tài)框架的數(shù)量
減少應(yīng)用程序大小,從而減少內(nèi)存頁面的使用(這就是我制作 Emerge 的原因!)
將代碼移出 +加載以及靜態(tài)初始化程序
使用 更少的類
將工作推遲到繪制第一個(gè)框架后
參考鏈接:
[1] The symbol from dyldinfo is mangled, you can get the human readable name with xcrun swift-demangle '_$sSHMp'. [2] Exports are the second piece of a bind. One binary binds to symbols exported from its dependencies. [3] The same goes for binds, a pointer is actually a union of rebase and bind (dyld_chained_ptr_64_bind) with a single bit used to differentiate the two. Binds also require the imported symbol name which isn’t discussed here. [4] https://asciiwwdc.com/2016/sessions/406
iOS 15 內(nèi)置原生壁紙下載 優(yōu)酷 iOS 插件化頁面架構(gòu)方法 這也行?iOS后臺(tái)鎖屏監(jiān)聽搖一搖 189.31G iOS 學(xué)習(xí)資料分享 iOS APP圖標(biāo)版本化
評(píng)論
圖片
表情

