iOS進階之路——理解 Xcode 編譯系統

来源:https://www.cnblogs.com/chengxyyh/archive/2020/06/11/13095602.html
-Advertisement-
Play Games

本文來自 iOSTips ,作者 Vadim Bulavin 任何 iOS 源代碼在設備上運行之前都需要編譯器的一系列處理,這個過程通常由 Xcode Build System 完成。在這篇文章中,我將介紹 Xcode Build System 的每一個部分。 為何要學編譯知識 說說 OCLint ...


本文來自 iOSTips ,作者 Vadim Bulavin

任何 iOS 源代碼在設備上運行之前都需要編譯器的一系列處理,這個過程通常由 Xcode Build System 完成。在這篇文章中,我將介紹 Xcode Build System 的每一個部分。

為何要學編譯知識

說說 OCLint 、SwiftLint 實現原理是怎樣的?
如何編寫 Clang 插件?
Obfuscator-LLVM 在 iOS 中如何實現混淆加固?
iOS 中 Bitcode 到底是如何優化 IPA 包的?
如果以上問題你都可以說個大概,請忽略本文,如果你對以上問題一知半解,但又很感興趣,那麼學習並掌握編譯原理相關知識的過程中,你便會自己找到答案,好了接下來我將大概的介紹 iOS 開發中需要瞭解的編譯流程。

語言處理系統

語言處理系統讓自己輸出一個可執行程式的一組任意源語言編寫的指令。它允許程式員使用高級語言而不是寫作機器代碼大大減少了編程的複雜性。

我們日常使用的語言處理系統 iOS 或 macOS 開發 叫做 Xcode Build System。

Xcode Build System

Xcode 構建系統的主要目的是協調執行各種構建任務,最終將產生一個可執行程式。

Xcode 通過運行一系列編譯器工具集將 iOS 源碼按一定的順序編譯鏈接生成可執行文件,而無需你手動操作,關心編譯鏈接背後複雜的過程。

大部分的語言處理系統,包括 Xcode Build Sytem,包括以下 5 個部分:

  • Preprocessor

  • Compiler

  • Assembler

  • Linker

  • Loader

這五部分組合起來是下麵的流程圖:

讓我們仔細看看每一個步驟。

Preprocessing

預處理步驟的目的是將你的程式做一些處理然後可提供給編譯器。它會處理巨集定義、發現依賴關係、解決預處理器指令。

Xcode 解決依賴關係通過底層 llbuild 構建系統。它是開源的,你可以在 Github swift-llbuild 頁面瞭解更多信息。

Compiler

編譯器是一個程式,將一種語言的源程式用另一種語言映射到一個語義上等價的目標程式。換句話說,它轉換Swift、objective - C和C / C++ 代碼到機器碼。

Xcode 使用兩個不同的編譯器:一個用於 Swift ,另一個用於Objective - C, Objective - C + +和 C / C++文件。

clang 是蘋果官方的 C 語言編譯器。它是開源在:swift-clang。

swiftc 是 Xcode 用來編譯和運行 Swift 源代碼的 Swift 編譯器。

編譯器工作流程如下:

編譯器由兩個主要部分:前端和後端。

前端負責詞法分析,語法分析,生成中間代碼;它還創建並管理符號表,收集關於源程式的信息。

符號表存儲名稱的變數,函數,類,你的名字,每個符號映射到特定的數據。

編譯原理之美

Swift 編譯器,中間語言表示名為 Swift Intermediate Language(SIL)。它是用於進一步分析和優化的代碼。不可能直接從 Swift 中間語言生成機器代碼,因此 SIL 經歷了一系列轉變到 LLVM 中間表示。

後端以中間代碼作為輸入,進行行架構無關的代碼優化,接著針對不同架構生成不同的彙編代碼。

Assembler

Assembler 翻譯開發者可讀的彙編代碼為可重定位的機器碼,最終生成包含數據和代碼的 Mach-O 文件。

機器代碼是一種數字語言,表示一組指令,可以直接由 CPU 執行。它被是可重定位的,因為無論目標文件的地址空間在哪,它將執行的指令相對地址。

Mach-O 文件是一種特殊的 iOS 和 MacOS 文件格式,操作系統用它來描述對象文件、可執行文件和庫。它是一串位元組組合形成的有意義的程式塊,將運行在 ARM 處理器上或英特爾處理器。

Linker

鏈接器將各種對象文件和庫鏈接合併為一個可以在 iOS 或 macOS 系統上運行的 Mach-O 可執行文件。鏈接器主要有兩種文件作為輸入,包括這些對象文件的彙編程式和庫的幾種類型(.dylib, .tbd 和 .a)。

鏈接器的作用,就是完成變數、函數符號和其地址綁定這樣的任務。例如,如果在代碼中使用 printf , 鏈接器鏈接這個符號和 libc 庫 printf 函數實現的地方。通常在編譯階段通過創建符號表來解決不同對象文件和庫的引用。

Loader

最後,載入程式是操作系統的一部分,將一個程式載入到記憶體中,並運行執行它。載入程式負責分配運行程式記憶體空間和初始化寄存器所需的初始狀態。

總結

作為 iOS 和 macOS 開發者我們主要使用 Xcode Build System 編譯構建我們的應用程式。它的主要組件是:預處理、編譯器、彙編器、連接器和載入程式。Xcode 使用不同的編譯器(swiftc 和 clang)編譯 Swift 和 Objective-C。

對於初學者和經驗豐富的開發人員來說學習掌握 編譯原理基礎知識都頗有益處,這裡有一張宮文學老師《編譯原理之美》的關於編譯知識結構體系的思維導圖,可以拿來對每個知識點系統學習。

作為一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是一個我的iOS交流群:519832104 不管你是小白還是大牛歡迎入駐,分享經驗,討論技術,大家一起交流學習成長!

另附上一份各好友收集的大廠面試題,需要iOS開發學習資料、面試真題,可以添加iOS開發學習交流群,進群可自行下載!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 42.統計APP應用的DB連接及IP情況 select b.hostname ,a.client_net_address, b.program_name ,count(1) as Qtyfrom sys.dm_exec_connections a(nolock) inner join sys.sys ...
  • 在開發過程中,埋點可以解決兩大類問題:一是瞭解用戶使用 App 的行為,二是降低分析線上問題的難度。目前,iOS 開發中常見的埋點方式,主要包括: 代碼埋點 可視化埋點 無埋點 代碼埋點 代碼埋點主要就是通過手寫代碼的方式來埋點,能很精確的在需要埋點的代碼處加上埋點的代碼,可以很方便地記錄當前環境的 ...
  • 分享近期 GitHub 上比較流行的 22 個和 iOS 開發相關的開源項目。 包括開發輔助工具,非同步編程庫,JSON 解析,移動端資料庫,圖像視頻處理,網路請求,UI 框架、組件,演算法、數據結構等內容。 Accio 使用 Swift 編寫的 iOS/tvOS/watchOS/macOS 依賴管理工 ...
  • 背景 過完年來北京之後,有準備看看機會,也是想瞭解下市場行情。簡歷沒有投太多,只定向投了頭條教育部門、抖音、快手、阿裡,這些公司。 頭條和阿裡的簡歷都沒過,肯定是亮點太少吧。只有快手簡歷過了,快手是三輪技術面+一輪HR面,前兩輪技術都比較順利,到第三輪卻栽了,很痛心o(╥﹏╥)o。目前就不考慮換工作 ...
  • 在移動開發中,App 的閃退率是工程師十分關註且又頭疼的事情。去年,網易杭州研究院曾經針對 crash 的防護有提出『大白健康系統--iOS APP 運行時 Crash 自動修複系統』方案,使得 crash 防護這個想法真正被落實,但至今該方案的具體實現並沒有被開源。經過一年的時間,圈子裡也有一些開 ...
  • 將Android Studio 升級到4.0然後創建一個新項目,編譯出現“ gradle 前言中不允許有內容” 的錯誤,在網上找了很多資料,眾說紛紜,但都沒有解決我的問題,最後反覆摸索把問題解決了。 1.清除gradle的所有緩存。 2.修改gradle 的版本,4.0支持的最的gradle 版本是 ...
  • 背景 啟動是App給用戶的第一印象,對用戶體驗至關重要。抖音的業務迭代迅速,如果放任不管,啟動速度會一點點劣化。為此抖音iOS客戶端團隊做了大量優化工作,除了傳統的修改業務代碼方式,我們還做了些開拓性的探索,發現修改代碼在二進位文件的佈局可以提高啟動性能,方案落地後在抖音上啟動速度提高了約15%。 ...
  • ####話不多說,先上效果圖 本文參考簡書博客:《這才是Android設置界面的正確做法👌👌👌》寫成,在其基礎上刪改並增加了一些內容。建議新視窗打開原文,在本文講述不清楚的地方參考原文去尋找答案。 其實設置界面,不需要自己去一個一個選項地去做。Android為我們提供了一些封裝好的東西,那就是 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...