Xcode工程文件project.pbxproj小结

Xcode工程文件project.pbxproj小结

简介

project.pbxproj 文件被包含于 Xcode 工程文件 *.xcodeproj 之中,存储着 Xcode 工程的各项配置参数。它本质上是一种旧风格的 Property List 文件,历史可追溯到 NeXT 的 OpenStep。由于有Xcode工具的存在,我们一般不需要与pbxproj直接打交道,通过General、Build Settungs或者Info等面板,就可以完成项目工程配置信息的修改。
一般格式如下:
数组用小括号括起来并用逗号隔开元素;字典用大括号括起来并用分号隔开键值对,键值之间用等号连接;二进制数据用尖括号括起来
</br>
接下来我们就依据一个具体的project.pbxproj文件来看看文件的具体内容;
首先使用Xcode新建一个项目文件,然后找到工程文件*.xcodeproj 邮件显示包内容就可以看到project.pbxproj文件,使用熟悉的编辑器打开,可以看到一些貌似混乱却又组织严密的内容。

文件的组织规则

对于NeXTSTEP格式的Property List 文件来说,整个的project.pbxproj文件就是一个字典,里面最外层有5个键值对,key分别为:

archiveVersion  
classes  
objectVersion  
objects   
rootObject  

其中重要的 Key 是 objects 和 rootObject。其他字段目前看来是固定的:

archiveVersion = 1;
classes = {
};
objectVersion = 46;

</br>
上面说到这个文件看似混乱,实质上却是组织清晰,最好的方法就是顺着 rootObject 的各个属性对应的 UUID 在 objects 中找到对应的对象,然后一层层看下去。这样整个文件的配置信息存放方式就慢慢摸清了(rootObject就好像一个入口函数),具体的配置实现是在 objects这个域里面的,里面每一项的又是一个字典,key是UUID,Value 依然是个字典。下面可以看到rootObject对应的value也可以在objects中找到具体的值。objects 中的键值对被分成了若干个 section,虽然 section 的顺序是 Xcode 私有 API 钦定的,但每个 section 内部的键值对会根据 Key 的字典序排列,以此增加可读性。
此外,这里还要补充一下:
project.pbxproj文件使用UUID 作为交叉引用的索引,保证每个配置信息对象的唯一性。因为 UUID 根据机器硬件和时间戳生成,避免了多人在同一时间段操作修改工程文件带来的问题。也就是说工程中每项配置对象都有个唯一的 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顾名思义就是工程,对应构建可执行的二进制目标程序或库,里面包含了编译工程所需的全部信息。
1、isa 可以把每个value看做一个对象,可以发现每一个value都有一个isa字段,代表value的类型。
2、attributes 属性,包含一些编译器的基本信息,版本,以及项目中的target,每一个target一个UUID其中,Xcode自动创建的项目里面有三个target一个就是所要编译的APP主target,其余两个为test Target,可以看到其余两个target中有一个字段TestTargetID指向主target,可以理解为依赖相关吧。
3、buildConfigurationList 配置列表 指向一个配置字典 XCConfigurationList 类型类型(稍后讲)
4、compatibilityVersion 应该是兼容版本 目前看来是 Xcode 3.2
5、developmentRegion 语言版本,English英语
6、hasScannedForEncodings 是否已经扫描了文件编码信息
7、knownRegions 不同区域的本地资源文件列表
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是一个构建配置相关元素的列表,里面有一个项目文件(HelloWorld),三个target(HelloWorld、HelloWorldTests和HelloWorldUITests)对应于你在Xcode界面中看到的这样,如图,每一个都有相对应的配置属性buildConfigurations,而每个配置属性都有两个的版本(Debug和Release)
那Debug和Release又对应什么呢?是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构建具体的配置元素,也就是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 文件组织形式文件的组织结构,可以嵌套,可以看到子文件列表放在key为children的字典中value是一个数组,如果数组中的值指向的是一个文件夹类型的,则再生成一个字典,一直到底指向最初的文件,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 项目所引用的每一个外部文件,比如源代码文件、资源文件、库文件、生成目标文件等,每一个外部文件都可以在这里找到,也就是在Xcode的文件导航栏所看到的文件组织形式,如图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,对应于生成的可执行二进制程序或库文件的本地构建目标对象,也就是Xcode我们看到的这三个target目标对象。里面的主要内容是:
1、buildConfigurationList 这个我们在讲述PBXProject时已经介绍过,是一个配置相关元素相关的列表。
2、buildPhases 构建阶段所涉及的源文件(PBXSourcesBuildPhase类型)、框架(PBXFrameworksBuildPhase类型)和资源(PBXResourcesBuildPhase)以数组形式组织。
3、buildRules 指定了不同文件类型该如何编译
4、dependencies 列出了在Xcode build phase tab中列出的target依赖项
5、productReference 目标文件(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 代表构建阶段需要复制的资源文件 文件组织在key为files的value中的数组列表里,每个元素为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构建的链接阶段

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 构建阶段需要复制的资源文件,包括xib文件、故事板(storyboard)、图片和plist文件等其他资源文件。链接至PBXBuildFile文件



到这里,整个project.pbxproj 文件基本走了一遍,我们也对整个文件的组织结构有了一个初步的了解,里面有些字段的含义也许不是很清楚,但是并不影响我们对文件结构的理解。如果想看更深的一步了解,可以参看这里
Cocoapods正是通过它的组件Xcodeproj操作project.pbxproj文件来对工程结构进行修改。
最后附上一张整体的流程图:


参考文献:
1、聊聊 Xcode 项目文件中的 project.pbxproj
2、通过Xcodeproj深入探究Xcode工程文件 一
3、Xcode工程文件的格式说明
4、project.pbxproj,最熟悉的“陌生人”

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容