Xcode工程文件project.pbxproj小結(jié)
簡介
project.pbxproj 文件被包含于 Xcode 工程文件 *.xcodeproj 之中,存儲著 Xcode 工程的各項配置參數(shù)。它本質(zhì)上是一種舊風(fēng)格的 Property List 文件,歷史可追溯到 NeXT 的 OpenStep。由于有Xcode工具的存在,我們一般不需要與pbxproj直接打交道,通過General、Build Settungs或者Info等面板,就可以完成項目工程配置信息的修改。
一般格式如下:
數(shù)組用小括號括起來并用逗號隔開元素;字典用大括號括起來并用分號隔開鍵值對,鍵值之間用等號連接;二進制數(shù)據(jù)用尖括號括起來
</br>
接下來我們就依據(jù)一個具體的project.pbxproj文件來看看文件的具體內(nèi)容;
首先使用Xcode新建一個項目文件,然后找到工程文件*.xcodeproj 郵件顯示包內(nèi)容就可以看到project.pbxproj文件,使用熟悉的編輯器打開,可以看到一些貌似混亂卻又組織嚴(yán)密的內(nèi)容。
文件的組織規(guī)則
對于NeXTSTEP格式的Property List 文件來說,整個的project.pbxproj文件就是一個字典,里面最外層有5個鍵值對,key分別為:
archiveVersion
classes
objectVersion
objects
rootObject
其中重要的 Key 是 objects 和 rootObject。其他字段目前看來是固定的:
archiveVersion = 1;
classes = {
};
objectVersion = 46;
</br>
上面說到這個文件看似混亂,實質(zhì)上卻是組織清晰,最好的方法就是順著 rootObject 的各個屬性對應(yīng)的 UUID 在 objects 中找到對應(yīng)的對象,然后一層層看下去。這樣整個文件的配置信息存放方式就慢慢摸清了(rootObject就好像一個入口函數(shù)),具體的配置實現(xiàn)是在 objects這個域里面的,里面每一項的又是一個字典,key是UUID,Value 依然是個字典。下面可以看到rootObject對應(yīng)的value也可以在objects中找到具體的值。objects 中的鍵值對被分成了若干個 section,雖然 section 的順序是 Xcode 私有 API 欽定的,但每個 section 內(nèi)部的鍵值對會根據(jù) Key 的字典序排列,以此增加可讀性。
此外,這里還要補充一下:
project.pbxproj文件使用UUID 作為交叉引用的索引,保證每個配置信息對象的唯一性。因為 UUID 根據(jù)機器硬件和時間戳生成,避免了多人在同一時間段操作修改工程文件帶來的問題。也就是說工程中每項配置對象都有個唯一的 UUID,然后其他配置對象想引用某個配置對象直接使用它的 UUID 即可。這就跟我們編程時使用指針指向某個對象的地址一樣,其他對象的屬性想引用它,只需要給屬性傳個指針地址就行了。
下面我就從rootObject開始簡單的走一遍,大概了解一下此文件的配置方式。
rootObject
rootObject = 662A377C1DB7D8B00038B7DB /* Project object */;
從注釋上就可以看出指向一個UUID為662A377C1DB7D8B00038B7DB的Project object字典
Project object
/* Begin PBXProject section */
662A377C1DB7D8B00038B7DB /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = Apress;
TargetAttributes = {
662A37831DB7D8B00038B7DB = {
CreatedOnToolsVersion = 8.0;
ProvisioningStyle = Automatic;
};
662A379C1DB7D8B00038B7DB = {
CreatedOnToolsVersion = 8.0;
ProvisioningStyle = Automatic;
TestTargetID = 662A37831DB7D8B00038B7DB;
};
662A37A71DB7D8B00038B7DB = {
CreatedOnToolsVersion = 8.0;
ProvisioningStyle = Automatic;
TestTargetID = 662A37831DB7D8B00038B7DB;
};
};
};
buildConfigurationList = 662A377F1DB7D8B00038B7DB /* Build configuration list for PBXProject "HelloWorld" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 662A377B1DB7D8B00038B7DB;
productRefGroup = 662A37851DB7D8B00038B7DB /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
662A37831DB7D8B00038B7DB /* HelloWorld */,
662A379C1DB7D8B00038B7DB /* HelloWorldTests */,
662A37A71DB7D8B00038B7DB /* HelloWorldUITests */,
);
};
/* End PBXProject section */

PBXProject顧名思義就是工程,對應(yīng)構(gòu)建可執(zhí)行的二進制目標(biāo)程序或庫,里面包含了編譯工程所需的全部信息。
1、isa 可以把每個value看做一個對象,可以發(fā)現(xiàn)每一個value都有一個isa字段,代表value的類型。
2、attributes 屬性,包含一些編譯器的基本信息,版本,以及項目中的target,每一個target一個UUID其中,Xcode自動創(chuàng)建的項目里面有三個target一個就是所要編譯的APP主target,其余兩個為test Target,可以看到其余兩個target中有一個字段TestTargetID指向主target,可以理解為依賴相關(guān)吧。
3、buildConfigurationList 配置列表 指向一個配置字典 XCConfigurationList 類型類型(稍后講)
4、compatibilityVersion 應(yīng)該是兼容版本 目前看來是 Xcode 3.2
5、developmentRegion 語言版本,English英語
6、hasScannedForEncodings 是否已經(jīng)掃描了文件編碼信息
7、knownRegions 不同區(qū)域的本地資源文件列表
8、mainGroup Xcode的文件組織形式,可以理解為文件層次 PBXGroup 類型
9、productRefGroup 編譯后的輸出文件 PBXGroup 類型
10、projectDirPath,projectRoot 項目路徑和項目的根目錄 目前為空
11、targets 項目下的三個target對象 PBXNativeTarget類型
從上到下,我們來看一下所用的類型。
XCConfigurationList
/* Begin XCConfigurationList section */
662A377F1DB7D8B00038B7DB /* Build configuration list for PBXProject "HelloWorld" */ = {
isa = XCConfigurationList;
buildConfigurations = (
662A37AF1DB7D8B00038B7DB /* Debug */,
662A37B01DB7D8B00038B7DB /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
662A37B11DB7D8B00038B7DB /* Build configuration list for PBXNativeTarget "HelloWorld" */ = {
isa = XCConfigurationList;
buildConfigurations = (
662A37B21DB7D8B00038B7DB /* Debug */,
662A37B31DB7D8B00038B7DB /* Release */,
);
defaultConfigurationIsVisible = 0;
};
662A37B41DB7D8B00038B7DB /* Build configuration list for PBXNativeTarget "HelloWorldTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
662A37B51DB7D8B00038B7DB /* Debug */,
662A37B61DB7D8B00038B7DB /* Release */,
);
defaultConfigurationIsVisible = 0;
};
662A37B71DB7D8B00038B7DB /* Build configuration list for PBXNativeTarget "HelloWorldUITests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
662A37B81DB7D8B00038B7DB /* Debug */,
662A37B91DB7D8B00038B7DB /* Release */,
);
defaultConfigurationIsVisible = 0;
};
/* End XCConfigurationList section */
XCConfigurationList是一個構(gòu)建配置相關(guān)元素的列表,里面有一個項目文件(HelloWorld),三個target(HelloWorld、HelloWorldTests和HelloWorldUITests)對應(yīng)于你在Xcode界面中看到的這樣,如圖,每一個都有相對應(yīng)的配置屬性buildConfigurations,而每個配置屬性都有兩個的版本(Debug和Release)
那Debug和Release又對應(yīng)什么呢?是XCBuildConfiguration:
/* Begin XCBuildConfiguration section */
662A37AF1DB7D8B00038B7DB /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
662A37B01DB7D8B00038B7DB /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
·
·
·
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
·
·
·
/* End XCBuildConfiguration section */

XCBuildConfiguration構(gòu)建具體的配置元素,也就是Xcode的Build Setting面板中所涉及的選項。至于每個字段所代表的含義可再深入研究。
PBXGroup
/* Begin PBXGroup section */
662A377B1DB7D8B00038B7DB = {
isa = PBXGroup;
children = (
662A37861DB7D8B00038B7DB /* HelloWorld */,
662A37A01DB7D8B00038B7DB /* HelloWorldTests */,
662A37AB1DB7D8B00038B7DB /* HelloWorldUITests */,
662A37851DB7D8B00038B7DB /* Products */,
);
sourceTree = "<group>";
};
662A37851DB7D8B00038B7DB /* Products */ = {
isa = PBXGroup;
children = (
662A37841DB7D8B00038B7DB /* HelloWorld.app */,
662A379D1DB7D8B00038B7DB /* HelloWorldTests.xctest */,
662A37A81DB7D8B00038B7DB /* HelloWorldUITests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
662A37861DB7D8B00038B7DB /* HelloWorld */ = {
isa = PBXGroup;
children = (
662A378A1DB7D8B00038B7DB /* AppDelegate.h */,
662A378B1DB7D8B00038B7DB /* AppDelegate.m */,
662A378D1DB7D8B00038B7DB /* ViewController.h */,
662A378E1DB7D8B00038B7DB /* ViewController.m */,
662A37901DB7D8B00038B7DB /* Main.storyboard */,
662A37931DB7D8B00038B7DB /* Assets.xcassets */,
662A37951DB7D8B00038B7DB /* LaunchScreen.storyboard */,
662A37981DB7D8B00038B7DB /* Info.plist */,
662A37871DB7D8B00038B7DB /* Supporting Files */,
);
path = HelloWorld;
sourceTree = "<group>";
};
662A37871DB7D8B00038B7DB /* Supporting Files */ = {
isa = PBXGroup;
children = (
662A37881DB7D8B00038B7DB /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
662A37A01DB7D8B00038B7DB /* HelloWorldTests */ = {
isa = PBXGroup;
children = (
662A37A11DB7D8B00038B7DB /* HelloWorldTests.m */,
662A37A31DB7D8B00038B7DB /* Info.plist */,
);
path = HelloWorldTests;
sourceTree = "<group>";
};
662A37AB1DB7D8B00038B7DB /* HelloWorldUITests */ = {
isa = PBXGroup;
children = (
662A37AC1DB7D8B00038B7DB /* HelloWorldUITests.m */,
662A37AE1DB7D8B00038B7DB /* Info.plist */,
);
path = HelloWorldUITests;
sourceTree = "<group>";
};
/* End PBXGroup section */
PBXGroup 文件組織形式文件的組織結(jié)構(gòu),可以嵌套,可以看到子文件列表放在key為children的字典中value是一個數(shù)組,如果數(shù)組中的值指向的是一個文件夾類型的,則再生成一個字典,一直到底指向最初的文件,PBXFileReference類型
PBXFileReference
/* Begin PBXFileReference section */
662A37841DB7D8B00038B7DB /* HelloWorld.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorld.app; sourceTree = BUILT_PRODUCTS_DIR; };
662A37881DB7D8B00038B7DB /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
662A378A1DB7D8B00038B7DB /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
662A378B1DB7D8B00038B7DB /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
·
·
·
662A37A81DB7D8B00038B7DB /* HelloWorldUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HelloWorldUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
662A37AC1DB7D8B00038B7DB /* HelloWorldUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HelloWorldUITests.m; sourceTree = "<group>"; };
662A37AE1DB7D8B00038B7DB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
PBXFileReference 項目所引用的每一個外部文件,比如源代碼文件、資源文件、庫文件、生成目標(biāo)文件等,每一個外部文件都可以在這里找到,也就是在Xcode的文件導(dǎo)航欄所看到的文件組織形式,如圖3。

productRefGroup
類似于mainGroup
PBXNativeTarget
/* Begin PBXNativeTarget section */
662A37831DB7D8B00038B7DB /* HelloWorld */ = {
isa = PBXNativeTarget;
buildConfigurationList = 662A37B11DB7D8B00038B7DB /* Build configuration list for PBXNativeTarget "HelloWorld" */;
buildPhases = (
662A37801DB7D8B00038B7DB /* Sources */,
662A37811DB7D8B00038B7DB /* Frameworks */,
662A37821DB7D8B00038B7DB /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = HelloWorld;
productName = HelloWorld;
productReference = 662A37841DB7D8B00038B7DB /* HelloWorld.app */;
productType = "com.apple.product-type.application";
};
662A379C1DB7D8B00038B7DB /* HelloWorldTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 662A37B41DB7D8B00038B7DB /* Build configuration list for PBXNativeTarget "HelloWorldTests" */;
buildPhases = (
662A37991DB7D8B00038B7DB /* Sources */,
662A379A1DB7D8B00038B7DB /* Frameworks */,
662A379B1DB7D8B00038B7DB /* Resources */,
);
buildRules = (
);
dependencies = (
662A379F1DB7D8B00038B7DB /* PBXTargetDependency */,
);
name = HelloWorldTests;
productName = HelloWorldTests;
productReference = 662A379D1DB7D8B00038B7DB /* HelloWorldTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
662A37A71DB7D8B00038B7DB /* HelloWorldUITests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 662A37B71DB7D8B00038B7DB /* Build configuration list for PBXNativeTarget "HelloWorldUITests" */;
buildPhases = (
662A37A41DB7D8B00038B7DB /* Sources */,
662A37A51DB7D8B00038B7DB /* Frameworks */,
662A37A61DB7D8B00038B7DB /* Resources */,
);
buildRules = (
);
dependencies = (
662A37AA1DB7D8B00038B7DB /* PBXTargetDependency */,
);
name = HelloWorldUITests;
productName = HelloWorldUITests;
productReference = 662A37A81DB7D8B00038B7DB /* HelloWorldUITests.xctest */;
productType = "com.apple.product-type.bundle.ui-testing";
};
/* End PBXNativeTarget section */

PBXNativeTarget,對應(yīng)于生成的可執(zhí)行二進制程序或庫文件的本地構(gòu)建目標(biāo)對象,也就是Xcode我們看到的這三個target目標(biāo)對象。里面的主要內(nèi)容是:
1、buildConfigurationList 這個我們在講述PBXProject時已經(jīng)介紹過,是一個配置相關(guān)元素相關(guān)的列表。
2、buildPhases 構(gòu)建階段所涉及的源文件(PBXSourcesBuildPhase類型)、框架(PBXFrameworksBuildPhase類型)和資源(PBXResourcesBuildPhase)以數(shù)組形式組織。
3、buildRules 指定了不同文件類型該如何編譯
4、dependencies 列出了在Xcode build phase tab中列出的target依賴項
5、productReference 目標(biāo)文件(PBXFileReference)
PBXSourcesBuildPhase
/* Begin PBXSourcesBuildPhase section */
662A37801DB7D8B00038B7DB /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
662A378F1DB7D8B00038B7DB /* ViewController.m in Sources */,
662A378C1DB7D8B00038B7DB /* AppDelegate.m in Sources */,
662A37891DB7D8B00038B7DB /* main.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
662A37991DB7D8B00038B7DB /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
662A37A21DB7D8B00038B7DB /* HelloWorldTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
662A37A41DB7D8B00038B7DB /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
662A37AD1DB7D8B00038B7DB /* HelloWorldUITests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
PBXSourcesBuildPhase 代表構(gòu)建階段需要復(fù)制的資源文件 文件組織在key為files的value中的數(shù)組列表里,每個元素為PBXBuildFile類型。
PBXBuildFile
/* Begin PBXBuildFile section */
662A37891DB7D8B00038B7DB /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 662A37881DB7D8B00038B7DB /* main.m */; };
662A378C1DB7D8B00038B7DB /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 662A378B1DB7D8B00038B7DB /* AppDelegate.m */; };
662A378F1DB7D8B00038B7DB /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 662A378E1DB7D8B00038B7DB /* ViewController.m */; };
662A37921DB7D8B00038B7DB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 662A37901DB7D8B00038B7DB /* Main.storyboard */; };
662A37941DB7D8B00038B7DB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 662A37931DB7D8B00038B7DB /* Assets.xcassets */; };
662A37971DB7D8B00038B7DB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 662A37951DB7D8B00038B7DB /* LaunchScreen.storyboard */; };
662A37A21DB7D8B00038B7DB /* HelloWorldTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 662A37A11DB7D8B00038B7DB /* HelloWorldTests.m */; };
662A37AD1DB7D8B00038B7DB /* HelloWorldUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 662A37AC1DB7D8B00038B7DB /* HelloWorldUITests.m */; };
/* End PBXBuildFile section */
PBXBuildFile 代表文件元素,被PBXBuildPhase等作為文件包含或被引用的資源,其實里面fileRef指向最終的文件PBXFileReference。
PBXFrameworksBuildPhase
/* Begin PBXFrameworksBuildPhase section */
662A37811DB7D8B00038B7DB /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
662A379A1DB7D8B00038B7DB /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
662A37A51DB7D8B00038B7DB /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
PBXFrameworksBuildPhase用于framewrok構(gòu)建的鏈接階段
PBXResourcesBuildPhase
/* Begin PBXResourcesBuildPhase section */
662A37821DB7D8B00038B7DB /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
662A37971DB7D8B00038B7DB /* LaunchScreen.storyboard in Resources */,
662A37941DB7D8B00038B7DB /* Assets.xcassets in Resources */,
662A37921DB7D8B00038B7DB /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
662A379B1DB7D8B00038B7DB /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
662A37A61DB7D8B00038B7DB /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
PBXResourcesBuildPhase 構(gòu)建階段需要復(fù)制的資源文件,包括xib文件、故事板(storyboard)、圖片和plist文件等其他資源文件。鏈接至PBXBuildFile文件

到這里,整個project.pbxproj 文件基本走了一遍,我們也對整個文件的組織結(jié)構(gòu)有了一個初步的了解,里面有些字段的含義也許不是很清楚,但是并不影響我們對文件結(jié)構(gòu)的理解。如果想看更深的一步了解,可以參看這里。
Cocoapods正是通過它的組件Xcodeproj操作project.pbxproj文件來對工程結(jié)構(gòu)進行修改。
最后附上一張整體的流程圖:

參考文獻:
1、聊聊 Xcode 項目文件中的 project.pbxproj
2、通過Xcodeproj深入探究Xcode工程文件 一
3、Xcode工程文件的格式說明
4、project.pbxproj,最熟悉的“陌生人”