深入探讨:了解 Xcode 组和文件夹引用之间的区别

2024-01-18

StackOverflow 上的很多地方都已经提出并回答了这个问题。然而,我发现其中大多数虽然在技术上是正确的,但遗漏了一些具体细节,这些细节不仅解释了实际发生的情况,而且在尝试调试文件引用或构建问题时可能是有价值的信息。

我决定根据杰夫·阿特伍德的文章将其发布在这里关于鼓励发布自己的答案的自己的评论 https://stackoverflow.blog/2011/07/01/its-ok-to-ask-and-answer-your-own-questions/他说……

提出并回答自己的问题不仅是可以的,而且是明确鼓励的[...]我一直这样做!

因此,我添加了这些项目的详细解释,希望这些知识可以帮助其他人,就像它帮助我一样,特别是在消除 Xcode 9 以来最常见的思维误解方面,项目树镜像了磁盘上的文件夹,但实际情况并非如此。


深入研究组和文件夹引用

如上所述,围绕这个主题有很多关于 SO 的答案,所有这些都解释了基本的差异。然而,当涉及到行为和对实际情况的理解时,有一些微妙的细节被忽略,当您的项目或其更改未按预期工作时,这些细节可能会导致令人沮丧的体验。因此,我将提供更彻底的解释。希望这将有助于避免很多令人头痛的事情。

现在,让我们动手吧!

文件夹参考

文件夹引用是两者中更容易掌握的一个。它们是指向实际磁盘文件夹的简单指针。文件夹引用可以通过其蓝色图标来识别。

文件夹引用跟踪对其引用的文件夹内容的添加、重命名和删除,根据需要自动更新项目树,即使这些更改是从 Xcode 外部进行的。

您可以通过蓝色图标来识别文件夹引用。

文件夹引用的主要目的是将其内容作为任何选定目标的捆绑资源包含在内。

关于定位文件夹引用需要注意的重要事项:

  1. 您只能在文件夹参考级别选择目标,而不能在单个文件或子文件夹级别选择目标。这是一个全有或全无的补充。

  2. 文件夹引用中的任何源代码文件都会作为文件资源添加到捆绑包中,就像任何其他文件一样。他们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 假设,如果您的组结构镜像了物理磁盘并且您对它们进行了重命名/重新排序,那么您很可能还希望物理磁盘进行更新,因此它会为您完成此操作。虽然有点误导,但非常方便。

有了这些新知识,如果事情变得不正常并且没有按照您的预期工作,则可能是时候检查您的文件和组引用以及相对位置了。确保您的文件夹引用实际上指向您期望的位置,尤其是在升级旧项目时,并且您应该能够很快回到正轨。

无论如何,希望这能更好地解释事情。当然帮助了我们! :)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入探讨:了解 Xcode 组和文件夹引用之间的区别 的相关文章

  • 链接器命令失败,退出代码为 1 -- Firebase

    对 iOS 开发相当陌生 有些人在将 firebase 安装到我的 iOS 应用程序中时遇到了一些麻烦 本质上 该应用程序要做的就是从 Firebase 数据库中获取有关全国各地路线的信息 该信息将输出到表格视图 该表格视图将允许用户选择其
  • 在XCode中快速查看Swift变量的类型

    有没有什么快捷方式可以让我在 XCode 中快速查看 Swift 中任何变量的类型 Alt 单击返回 无快速帮助 类型推断非常棒 但是如果没有这些工具 生活就会变得困难 Either use Alt click to display the
  • 使用 c11 标准和 clang 来使用 strcpy_s

    我正在运行 OS X Sierra 并尝试编译一个使用的 c 程序strcpy s 但是我安装的 clang 编译器使用的是 c99 标准 但是据我读到的 https embeddedgurus com barr code 2017 08
  • Cordova 4.3.0 - 构建命令返回错误无法找到模块“Q”

    将 cordova 更新到版本 4 3 0 后 命令 cordova build 返回以下错误 module js 340 throw err Error Cannot find module Q at Function Module re
  • UICollectionView cellForItemAtIndexPath 未注册单元格

    我正在尝试使用UICollectionViewCell 因为我想显示的只是一张图像 我可以使用将图像添加到单元格中UIColor colorWithImage on the UICollectionViewCell s contentVie
  • 如何在按下按钮之前停止响应震动?

    我目前正在制作一个 iPhone 应用程序 动画会对轻微的震动做出反应 这是我的代码 static BOOL SJHShaking UIAcceleration last UIAcceleration current double thre
  • Xcode 未创建 .h 文件

    我使用的是 Xcode 6 0 1 我创建了一个自动生成 h 和 m 文件的新项目 当我尝试添加新的 Objective C 文件时 它仅创建 m 文件 h 文件未生成 我尝试了所有首选项 但没有找到一个显示 生成 h 文件 的选项 出于好
  • 带圆圈的 CGContextClearRect

    我正在创建一个应用程序 其中我试图清除rect of UIImageView 我已经实现了这一目标CGContextClearRect 但问题是它正在清除rect在方形中 我想在圆形中实现这种效果 到目前为止我已经尝试过 UITouch t
  • 与 UIActivityViewController 共享 PDF 文件

    我正在尝试使用共享 PDF 文件UIActivityViewController但是当我按下按钮时 我没有共享文件的选项 我怎样才能显示这些选项 https i stack imgur com ywDQw jpg https i stack
  • 收到断言失败错误

    加载其中包含 UITableView 的视图之一时 出现以下错误 有谁知道如何修理它 我已经尝试过删除 void tableView UITableView tableView commitEditingStyle UITableViewC
  • 如何以编程方式将传入的 iPhone 短信静音?

    我目前正在尝试使用AVSystemController根据用户的选择来静音系统噪音的私有框架 我目前正在通过以下方式将电话静音 AVSystemController object setVolumeTo 0 0 forCategory Ri
  • UIImage initWithContentsOfFile 不起作用

    我有问题 我想避免 UIImage imageNamed 所以我做了 UIImage prodImg UIImage alloc initWithContentsOfFile myimage png controller productIm
  • MonoTouch - 编辑 xib 时缺少头文件[重复]

    这个问题在这里已经有答案了 我使用的是 Mac OSX Lion 10 7 0 带有适用于 IOS 5 的 Xcode 4 2 和 Xamarin 的 MonoTouch 跨平台移动开发工具 允许您使用 C 和 NET 创建适用于 iOS
  • 拒绝访问特定目录中的特定文件类型

    对于某些应用程序 用户可以上传自己的文件 由于这可能是非常大的文件 因此他们可以通过自己的 FTP 客户端上传这些文件 当然 我不希望他们上传一些可以访问服务器上所有其他文件的 PHP 文件 我想要防止这种行为的方法之一是拒绝仅访问这些文件
  • 检查定位服务是否开启

    我一直在对 CoreLocation 进行一些研究 最近 我遇到了一个在其他地方 但在 Objective C 和 iOS 8 中 已经讨论过的问题 我觉得问这个问题有点傻 但是如何在 iOS 9 上使用 swift 检查是否启用了位置服务
  • 是否有针对不同屏幕尺寸的单独故事板?

    基本上我已经完成了一个应用程序 我唯一的问题是 ATM 机应用程序在设计时只考虑了 4 英寸显示屏 当在 3 5 英寸模拟器上运行时 应用程序会丢失 0 5 英寸 显然 那么我的问题是 如何在 Xcode 5 中为不同的屏幕尺寸设置不同的故
  • 升级到 Xcode 4.3.1 后,自动设备配置选项消失了?

    自从升级到 Xcode 4 3 1 以来 这是我第一次发布版本 在查看我的配置文件是否是最新的时 我还注意到不再显示自动更新设备配置 即 它应该出现在该屏幕截图中的位置对我来说没有出现 如何将新设备添加到团队配置文件中 https stac
  • Apple Watch 预构建操作可更改故事板 customModule 引用

    我目前有一个项目 其中包含同一应用程序的 3 个不同版本 不同的品牌等 该项目运行得很好 从那时起 我添加了 3 个新的 Apple Watch 目标 每个应用程序 版本 1 个 其中 2 个引用 主 Apple Watch 目标中的文件
  • ios水平居中约束问题?

    I am having hard time in learning constraints auto layout in iOS I have used any width any height I have a storyboard sc
  • iOS - UITableViewCell 使文本加粗

    我有一个字符串 NSString userInfo James Johnson james 我想做的就是大胆James Johnson并保留 james正常字体 所以我尝试过的是使用NSAttributedString但为了完成这个过程 我

随机推荐

  • 如何在 iPhone 中从左到右设置动画视图?

    如何对从左到右的视图过渡进行动画处理 类似推送视图 当我单击按钮时 视图应该从左向右转换 所以请指导我并提供一些示例链接 Thanks 假设你想从右边推view2来替换view1 Set up view2 view2 frame view1
  • 缩短 NSString?

    我有一个非常简单的问题 是否有内置方法来缩短字符串 如果没有 有人可以提供一个这样做的例子ObjC 例如 这是一个很长的字符串 应该成为 这是AV 它需要检查字符串是否超过一定数量的字符以及是否被缩短 这非常简单 NSString orig
  • 使用行号进行 SQL 逆透视

    我有一个带有 UNPIVOT 的 SELECT 语句 SELECT dycd acnam dycd dynam dycd value FROM GCATT dbo tblDaycode UNPIVOT dycd value FOR dycd
  • 使用多个外部库时如何避免“重新定义”?

    我有两个库 第三方 并且在每个库中它们都定义了两个具有相同名称的类 在头文件中 Lib A HeaderA h struct mycompare Some code Lib B HeaderB h struct mycompare Same
  • Laravel 未发布到 Redis

    我正在尝试在本地 RESTful API 中实现 Redis 发布 该 API 是在 Laravel 中构建的 以便稍后使用 Web Sockets 实现聊天系统 我打算稍后从 Node JS 服务器读取它们 我在用Redis publis
  • Bamboo - Angular 4 应用程序如何部署

    如何在竹子上部署我的 Angular 4 应用程序 我只是做一个简单的工作 1 git 2 npm install 3 ng build 顺利通过了 但是接下来我应该做什么呢 如何将其部署在服务器上 以便我可以从浏览器进入应用程序 我尝试将
  • 使用索引优化MYSQL数据库[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我正在研究学习商务模拟 http www learnbizsimulations com 一家自筹资金的初创公司 为管理教育领域进行模拟 a 我们的网
  • 应用程序清单文件在 Win 7 环境中导致问题

    我的应用程序已从 net 1 1 升级到 3 5 在 win 7 64 位环境中 我必须手动删除 app exe manifest 文件 否则启动时会崩溃 我使用 Visual Studio 部署和设置项目进行安装 在exe的应用程序设置本
  • 使用 jquery 按值更改/修改下拉列表文本

    我有带有值的下拉列表
  • 如何在 TypeScript 项目中导入节点模块。 ERR_REQUIRE_ESM

    我正在尝试将包 p limit 导入到我的打字稿项目中 当尝试使用运行项目时tsc node serve js 我遇到了下面的错误 我已经被困在这个问题上几个小时了 Error ERR REQUIRE ESM Must use import
  • pm2 可以运行“npm start”脚本吗

    pm2 有没有办法运行 npm start 脚本 或者你只需 要运行pm2 start app js 所以在开发中 npm start 然后在生产中使用 pm2 你会运行类似的东西 pm2 start npm start 有一个等效的方法可
  • android sqlite异常:java.lang.IllegalArgumentException:列'_id'不存在

    我创建了一个包含以下列的 sqlite 数据库 static final String dbName demoDB static final String tableName Employees static final String co
  • MySQL 错误:没有密钥长度的密钥规范

    我有一个主键为 varchar 255 的表 在某些情况下 255 个字符是不够的 我尝试将字段更改为文本 但出现以下错误 BLOB TEXT column message id used in key specification with
  • 如何获取元素的事件监听器

    有没有办法使用 HTML 页面上的 JavaScript 获取该页面上某个元素的所有事件侦听器的列表 注意 我知道我们可以使用 Chrome 开发工具事件侦听器查看它们 但我想使用页面的 JavaScript 来记录 访问查看列表 另外 我
  • 在 WPF 中动态添加网格和控件

    我现在正在制作一个显示系统中硬盘使用情况的应用程序 为此 我想动态生成网格和控件 如进度条和标签 以显示用法 是否有任何 XAML 模板可用于此目的 我使用以下代码在我的代码中动态生成控件 Label drivesLabel Label p
  • Django 表单选择字段的初始值被忽略

    我有这个表格 class UserUsesSourceForm forms Form some fields here username forms CharField label Username max length 30 help t
  • 如何推送到容器上的 git 服务器?

    在我的主机上 我可以创建第二个用户 admin and push使用以下命令到该用户的 git 文件夹 admin localhost folder 当我创建托管 git 服务器的 Docker 容器时 在公开之后port 22我如何git
  • 当 wpf 数据网格单元格中的值使用 MVVM 更改时如何引发事件?

    我需要使用 MVVM 设计模式的 wpf 数据网格方面的帮助 我有一个绑定到可观察集合的 datagid 网格中的第一列包含无法编辑的十进制值 第二列包含一个文本框 必须在其中输入十进制值 第三列必须显示第一列中的值与输入的第二列中的值之间
  • 在 ng-if 中调用 Javascript

    我有一些遗留的 jQuery 代码 这是一大块代码 所以我宁愿稍后再移植它 要使用它 我调用 legacyId legacyFunction 不过 事情是这样的 我有一个 ng if 在 ng if 中 我有 JavaScript 我可以在
  • 深入探讨:了解 Xcode 组和文件夹引用之间的区别

    StackOverflow 上的很多地方都已经提出并回答了这个问题 然而 我发现其中大多数虽然在技术上是正确的 但遗漏了一些具体细节 这些细节不仅解释了实际发生的情况 而且在尝试调试文件引用或构建问题时可能是有价值的信息 我决定根据杰夫 阿