iOS 開發:深入理解 Xcode 工程結構(一)轉

来源:https://www.cnblogs.com/jiuyi/archive/2018/12/18/10135551.html
-Advertisement-
Play Games

當我們新建一個 Cocoa 項目時,Xcode 會提供一系列的模板,類似前端的腳手架工具,只需要簡單的幾個選項,就可以配置好一個項目所需的基本環境。 這些基本環境配置一般包括: 編譯選項、證書鏈選項 項目 Target、單元測試 Target 基於 git 的版本控制管理 預設的源文件 編譯選項、證 ...


當我們新建一個 Cocoa 項目時,Xcode 會提供一系列的模板,類似前端的腳手架工具,只需要簡單的幾個選項,就可以配置好一個項目所需的基本環境。

這些基本環境配置一般包括:

  • 編譯選項、證書鏈選項

  • 項目 Target、單元測試 Target

  • 基於 git 的版本控制管理

  • 預設的源文件

當然我們也可以新建一個空白的 Project,然後手動去組裝這些東西。

由於蘋果的封閉性,對 Cocoa 項目的管理基本上都在 Xcode 中進行,這個 All-in-One 的強大工具提供了從文檔、編碼、調試、測試,再到簽名、打包、上線的全流程支持。

隨著開發的深入,我們的項目變得越來越複雜,各種鏈接庫、子工程相互引用,不同 Target、Scheme 配置混雜,還會遇到多人協作開發時詭異的衝突。即使是老鳥有時候也會一籌莫展,這時候就需要對 Xcode 工程結構以及管理機制有更加清晰的認識。

Scheme、Target、Project 和 Workspace

Schema、Target、Project 和 Workspace 是組成一個 Xcode 工程最核心的單元,也是我們首先需要理解的部分。

Target

Target 是我們工程中的最小可編譯單元,每一個 target 對應一個編譯輸出,這個輸出可以是一個鏈接庫,一個可執行文件或者一個資源包。它定義了這個輸出怎樣被 build 的所有細節,包括:

 

  • 編譯選項,比如使用的編譯器,目標平臺,flag,頭文件搜索路徑等等。

  • 哪些源碼或者資源文件會被編譯打包,哪些靜態庫、動態庫會被鏈接。

  • build 時的前置依賴、執行的腳本文件。

  • build 生成目標的簽名、Capabilities 等屬性。

我們平時在 Build Settings,Build Phases 中配置的各種選項,大部分都是對應到指定的 target 的。

每次我們在 Xcode 中 run/test/profile/analyze/archive 時,都必須指定一個 target。

工程中的 targets 有時候會共用很多代碼、資源,這些相似的 targets 可能對應同一個應用的不同版本,比如 iPad 版和 iPhone 版,或者針對不同市場的版本。

Project

Project 很好理解,就是一個 Xcode 工程,它管理這個工程下的 targets 集合以及它們的源碼,引用的資源,framework 等等

Project 是管理資源的容器,本身是無法被編譯的,所以每個 project 至少應該有一個可編譯的 target,否則就是一個空殼。一個 target 編譯時引用的資源是它所在 project 所有管理資源的子集。

我們也可以對 project 進行配置,包括基本信息和編譯選項(Build Settings)等,這些配置會應用到它管理的所有 targets 中,但是如果 target 有自己的配置,則會覆蓋 project 中對應的配置。

 

在很多情況下,我們的工程中只有一個 project。可以在 finder 中雙擊尾碼名為.xcodeproj 的文件,就可以直接打開單個 project 了。

如果我們需要從源碼編譯一個依賴庫,可以把這些源碼所在的工程作為主工程的subProject 添加到目錄結構中去:

然後將這個子工程的某個 target 作為主工程 target 的依賴,從而在 build 主工程 target 的時候,順便也會編譯子工程對應的 target。

這樣做的好處是你可以在一個視窗中同時修改主工程和子工程的源碼,並且一起進行編譯。

Workspace

上面所說的添加子工程的方法,已經很好的解決了不同項目中 target 依賴的問題了,那麼什麼時候需要用到 Workspace 呢?

當一個 target 被多個不同的項目依賴,或者 project 之間互相引用,那麼我們就需要把這些 projects 放到相同的層級上來。管理相同層級 projects 的容器就是 Workspace

和 projects,target 不同,workspace 是純粹的容器,不參與任何編譯鏈接過程,它主要管理:

  • Xcode 中的 projects,記錄它們在 Finder 中的引用位置。

  • 一些用戶界面的自定義信息(視窗的位置,順序,偏好等等)。

註意到,當你把不同的 projects 放到一個 workspace 中管理後,你仍然可以用 Xcode 單獨打開其中的某一個 project,但是如果它涉及到對其它 project target 的依賴,這時候你無法在這個單獨的視窗中編譯成功。

在 iOS 開發中,我們常常使用 Cocoapods 來管理三方庫,它會把這些三方庫的源碼組裝成一個 project,和主工程一起放入到 workspace 中,自動配置好主工程與 pods 庫之間的依賴。所以如果引入了 Cocoapods,我們必須打開這個新的 workspace 才能正常 build 原來的項目。關於 Cocoapods,我們在後面的文章中再詳細介紹

Scheme

日常開發中我們常常點擊 Xcode 左上角的 Run 箭頭來運行調試代碼,這其實就是執行了 Scheme 定義的一個任務。

針對一個指定的 target,scheme 定義了 build 這個 target 時使用的配置選項,執行的任務,環境參數等等。Scheme 可以理解為一個工作流,或者藍圖,當我們點擊 debug,test 按鈕時,Xcode 會按照 scheme 中的定義,去執行對應的工作流。

Scheme 中預設了六個主要的工作流: Build, Run, Test, Profile, Analyze, Archive。包括了我們對某個 target 的所有操作,每一個工作流都可以單獨配置。

Scheme 中最重要的一個配置是選擇 target 的 build configuration,對每一個 project,會有兩個預設的 build configuration:debug 和 release。

每個 configuration 對應了 build target 時不同的參數集,比如巨集,編譯器選項,bundle name 等等。我們可以在 target 的配置頁中更改這些選擇項,也可以自己創建新的 build configuration,比如為 App 創建免費和付費版本的配置。

除了 build configuration 外,scheme 還可以配置:

  • 運行時的環境變數(Environment Variables)

  • 啟動時設置給 UserDefaults 的參數(Arguments Passed on Launch)

  • App 執行時的系統語言、模擬的定位坐標、國家等環境參數

  • runtime,記憶體管理,日誌,幀率檢測等調試選項

另外有一些 debug 時十分有用的選項,也可以在 scheme 配置中找到。

一個 scheme 對應一個 target,同一個 target 可以有多個 scheme,通過靈活地配置 scheme,我們可以方便地管理不同環境下 App 的測試,調試,打包流程。

下表列舉了我們在 Scheme 中的常見配置選項:

選項說明
Pre(Post)-actions 指定在進行工作流之前(之後)執行的腳本,發送郵件通知等任務。
Launch 編譯完成後是否立即運行
Arguments Passed On Launch 指定一些運行時的參數,比如本地化語言的選項,Core Data 調試選項等
Environment Variables 指定環境變數,比如開啟僵屍記憶體,Malloc選項,I/O buffer大小等。
Application Language/Region App 運行使用的語言和國家
XPC Services 打開調試 XPC (應用間通信)
Queue Debugging 打開線程調試,會自動記錄運行時的線程信息。
Runtime Sanitization 是否打開運行時的一些調試選項,包括記憶體檢測、多線程檢測等等,在 debug 一些棘手的異常時十分有用
Memory Management 開啟一些記憶體管理相關的服務,包括記憶體塗抹,邊緣保護,動態記憶體分配保護,僵屍對象等等
Logging 配置調試過程中終端輸出的日誌
Runtime Sanitization 是否打開運行時的一些調試選項,包括記憶體檢測、多線程檢測等等,在 debug 棘手的異常時十分有用


本文參考:

    • Xcode Concepts (https://developer.apple.com/library/archive/featuredarticles/XcodeConcepts/Concept-Projects.html#//apple_ref/doc/uid/TP40009328-CH5-SW1)

    • Xcode and git: bridging the gap(https://robots.thoughtbot.com/xcode-and-git-bridging-the-gap)

    • Xcode Project vs. Xcode Workspace - Differences (https://stackoverflow.com/questions/21631313/xcode-project-vs-xcode-workspace-differences)

    • limit run script build phase to release configuration (https://stackoverflow.com/questions/3614017/how-can-i-limit-a-run-script-build-phase-to-my-release-configuration)

    • Xcode - xcworkspace and xcodeproj (http://neurocline.github.io/dev/2016/04/16/xcode-xcworkspace-and-xcodeproj.html)

    • Launch Arguments & Environment Variables (https://nshipster.com/launch-arguments-and-environment-variables/)


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

-Advertisement-
Play Games
更多相關文章
  • 本文是對MySQL中觸發器的總結,從觸發器概念出發,結合實例對創建觸發器、使用觸發器、刪除觸發器進行介紹。 ...
  • 定義自定義函數 調用 f1 函數 查詢 tmp 表中的數據 在查詢中調用 f1 函數 運行結果: 函數與存儲過程的區別 存儲過程: 1. 裡面包含 SQL 語句 2. intout, out 構造返回值 3. 調用方式:select 函數名(參數) 函數: 1. 裡面不能包含 SQL 語句 2. r ...
  • CHAR_LENGTH(str) 返回值為字元串str 的長度,長度的單位為字元。一個多位元組字元算作一個單字元。 CONCAT(str1,str2,...) 字元串拼接, 如有任何一個參數為NULL ,則返回值為 NULL。 CONCAT_WS(separator,str1,str2,...) 字元 ...
  • 問題 如何安裝並使用Oracle SQL Developer訪問Oracle。 步驟 Oracle SQL Developer是Oracle官方出品的免費圖形化開發工具,相對SQL*Plus來說,圖形化的界面便於操作,不必記憶大量的命令,輸出結果美觀。它的基本功能包括結果的格式化輸出,編輯器自動提示 ...
  • cmd命令中輸入:adb shell dumpsys activity activities 在一連串的輸出中找到Runing activities com.android.settings是包名. .HWSettings是activitie名稱 ...
  • 本文由雲+社區發表 SQLite 在移動端開發中廣泛使用,其使用質量直接影響到產品的體驗。 常見的 SQLite 質量監控一般都是依賴上線後反饋的機制,比如耗時監控或者用戶反饋。這種方式問題是: 事後發現,負面影響已經發生。 關註的只是沒這麼差。eg. 監控閾值為 500ms ,那麼一條可優化為 2 ...
  • 前期項目一直用的是Windows azure NotificationHub+Google Cloud Message 實現消息推送, 但是GCM google已經不再推薦使用,慢慢就不再維護了, 現在Google 主推 FCM, 另一方面,google在android生態中的許可權要求越來越嚴格,不 ...
  • 步驟:0. adb root0. adb shell0. ps | grep browser1. gdbserver :5039 --attach pid2. adb forward tcp:5039 tcp:5039 1. prebuilts/gcc/linux-x86/arm/arm-eabi- ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...