深入研究组和文件夹引用
如上所述,围绕这个主题有很多关于 SO 的答案,所有这些都解释了基本的差异。然而,当涉及到行为和对实际情况的理解时,有一些微妙的细节被忽略,当您的项目或其更改未按预期工作时,这些细节可能会导致令人沮丧的体验。因此,我将提供更彻底的解释。希望这将有助于避免很多令人头痛的事情。
现在,让我们动手吧!
文件夹参考
文件夹引用是两者中更容易掌握的一个。它们是指向实际磁盘文件夹的简单指针。文件夹引用可以通过其蓝色图标来识别。
文件夹引用跟踪对其引用的文件夹内容的添加、重命名和删除,根据需要自动更新项目树,即使这些更改是从 Xcode 外部进行的。
您可以通过蓝色图标来识别文件夹引用。
文件夹引用的主要目的是将其内容作为任何选定目标的捆绑资源包含在内。
关于定位文件夹引用需要注意的重要事项:
-
您只能在文件夹参考级别选择目标,而不能在单个文件或子文件夹级别选择目标。这是一个全有或全无的补充。
-
文件夹引用中的任何源代码文件都会作为文件资源添加到捆绑包中,就像任何其他文件一样。他们cannot从文件夹引用中编译。如果你想编译代码,它must成群结队!
现在,最后一点一开始可能看起来很奇怪/令人困惑,因为您在目标中包含源代码,但实际上并未编译它。但是,当您了解在文件夹引用上选择一个(或多个)目标实际上是在说“将此文件夹中的所有内容作为捆绑资源包含在内”(无论这些文件是什么)时,它就具有逻辑意义了。必须针对每个项目制定规则来说明“捆绑这个,但编译那个”会混淆“此文件夹代表捆绑资源”这一声明的简单性。
因此,如果您希望代码被编译,它必须位于一个组中。
Groups
另一方面,团体则更为复杂。用最简单的解释来说,它们是 Xcode 项目中的纯逻辑容器,用于存储和组织源代码文件的相对指针。它们仅存储在 Xcode 项目中,而不存储在磁盘上。
您可以通过黄色文件夹来标识项目中的组。
每个项目,无论是组本身还是组内的文件引用,都指定一个位置以及它与项目结构的关系。这可以在检查器的“身份和类型”部分找到。
值得注意的是...
- Groups can引用磁盘上的特定文件夹,但不必
- 文件参考must指向磁盘上的特定文件。
这些引用的存储方式取决于“位置”的值:
- 如果“位置”设置为“绝对路径”,则引用将包含该项目的整个磁盘路径。
- 如果将其设置为“相对于组”,则它首先确定组当前解析的内容,然后相对于该值存储引用。这将通过父组递归地向上传播。
图像上也有细微的差别。如果该组指向实际文件夹,您只会看到黄色文件夹。但是,如果该组未引用特定文件夹(即它仅是逻辑文件夹),您将在文件夹图标中看到一个小三角形。
此外,无论该组是否已连接,您始终可以通过查看检查器中的“完整路径”属性来查看组或其任何子级引用的当前物理位置。
再次强调,重要的是要注意您的逻辑“组”结构没事做与物理磁盘结构。人们经常犯这样的错误:认为从 Xcode 9 开始,这种说法并不正确,但请继续阅读以了解为什么这种误解仍然存在。
如前所述,组并不代表实际的磁盘上文件夹。它们是纯粹用于代码组织的简单逻辑分组。然而,他们可以point到实际的磁盘文件夹。您可以通过检查器“身份和类型”部分中“位置”下拉列表下的小文件夹按钮来设置哪个文件夹。您还可以通过按圆圈中的小 x 再次清除该关联。
现在这是棘手的部分。当处理不指向实际文件夹的组时,它们的全部目的只是帮助您作为用户以对您有意义的结构组织代码,并且让 Xcode 能够将磁盘上的实际路径解析为那些文件引用。
但是如果你有一个小组怎么办?does指向一个文件夹?现在一套全新的规则开始发挥作用。这些规则在 Xcode 9 中发生了变化。
Xcode 9之后,修改组名may修改磁盘名称,但是不必要。它会only如果组名称和物理文件夹名称相同,则执行此操作重命名之前的匹配。如果他们不这样做,那么他们实际上就“断开了联系”。
例如,假设您的项目中有一个名为“Virtual”的组,它指向磁盘上名为“Literal”的文件夹,如下所示...
Group On-disk Folder
----- --------------
Virtual -> Literal
如果将组“虚拟”重命名为“概念”,则磁盘上不会发生任何事情。
Conceptual -> Literal
如果您随后将“Conceptual”重命名为“Literal”,使其与磁盘上的实际文件夹名称匹配...
Literal -> Literal
...然后再次将“Literal”重命名为“Changed”,两个组and该文件夹将更新为“已更改”。
Changed -> Changed
注:这与where该文件夹位于磁盘上。这仅与名称本身有关,与其他无关。
我们去哪?
至于它在磁盘上的位置,事情也比看起来更复杂。如果您移动当前未指向实际磁盘文件夹的组,除了 Xcode 更新其在项目文件中存储项目项的相对路径的方式(使它们相对于更新的组结构)之外,不会发生任何事情。
但是,如果您移动当前指向文件夹的组--即使其名称与磁盘上的文件夹不匹配(这是一个关键点,也是关于“损坏的”项目树的常见混乱来源)——它指向的物理磁盘文件夹将被移动到相对于您将其拖到下面的任何组的新位置,以及所有磁盘上该文件夹中的项目无论您的项目中是否引用了!
例如,假设您的项目结构中有这个......
Project
GroupA -> Points to \Code\Project\GroupA
GroupB -> Points to \Some\Really\Deep\Path\Somewhere\Else\On\The\Disk\Entirely\GroupB
然后您拖动 GroupS,使其位于项目树中的 Group B 下,如下所示...
Project
GroupB
GroupA
由于 GroupA 指向磁盘上的物理文件夹(再次记住,这与组名称和目录名称是否匹配无关,只与组指向实际目录有关),因此磁盘上的目录和其所有内容,无论是否引用实际上会移动到
\Some\Really\Deep\Path\Somewhere\Else\On\The\Disk\Entirely\GroupB\GroupA
同样,您将其移动到目标群体的任何位置之下actual磁盘上的路径是。
现在,如果 GroupB 实际上没有指向文件夹,但 GroupA 却指向文件夹,那么最终位置resolvesGroupB 解析为磁盘上的位置,这意味着它会考虑其所有父组来确定位置。
最常见的场景
好消息是,对于 95% 的用例(确实如此),除非您正在处理遗留代码库或主动更改新项目的结构(物理磁盘文件夹结构)will与项目结构相匹配,并且所有这些文件夹引用都应设置为“相对于组”,这意味着这些组本质上是文件系统的镜像。这就是为什么人们认为从 Xcode 9 开始,您正在修改文件系统,但同样,您没有修改文件系统。您仍然只是修改组和文件引用。只是 Xcode 假设,如果您的组结构镜像了物理磁盘并且您对它们进行了重命名/重新排序,那么您很可能还希望物理磁盘进行更新,因此它会为您完成此操作。虽然有点误导,但非常方便。
有了这些新知识,如果事情变得不正常并且没有按照您的预期工作,则可能是时候检查您的文件和组引用以及相对位置了。确保您的文件夹引用实际上指向您期望的位置,尤其是在升级旧项目时,并且您应该能够很快回到正轨。
无论如何,希望这能更好地解释事情。当然帮助了我们! :)