繁体   English   中英

Xcode 更改未修改的故事板和 XIB 文件

[英]Xcode changes unmodified storyboard and XIB files

当多人协作时,从 git 工作流程的角度来看,情节提要相当痛苦。 例如,.storyboard 文件中的 XML 的起始<document>标记的toolsVersionsystemVersion属性被最新的文件操纵器碰巧运行的任何配置所改变。 精确同步每个人的 Xcode 版本似乎对toolsVersion有帮助,但systemVersion发生变化,具体取决于开发人员运行的特定 Mac 和/或 OS X 版本。

这是愚蠢的,但基本上是无害的。 然而,让我们担心的是,在其他时候,只需在git pull之后打开它们,就会自动对故事板进行一些其他更改。 也就是说,Alice 对 Storyboard 进行更改,提交并将它们推送到存储库。 然后 Bob 提取 Alice 的更改并打开故事板以进行进一步的更改。 在他打开故事板的那一刻,文件图标立即变为已修改但未保存的状态,并且git status显示发生了一些奇怪的变化。 所有这一切都没有 Bob 更改任何内容或自己保存文件。

我们看到的最常见的自动更改是故事板文件末尾附近整个<classes>标记层次结构的消失或重新出现。 我们还没有弄清楚是什么原因造成的。 我们可能在各种 .lproj 目录中有多个故事板的本地化版本,当在 Interface Builder 中打开它们时,类层次结构可能会自发地从某些中删除并添加到其他中,或者在某些中单独保留。 这会在git diff中引起很多噪音,但它实际上并没有破坏任何功能。 我们通常会选择性地将我们所做的实际更改添加到 git 的索引中,提交这些更改,然后丢弃自发的、无意义的<classes>更改。 这是为了保持提交小而漂亮,因为它们应该如此。 但是,最终,由于 Xcode 不断重新进行更改,并且有人只是愤怒地将它们与其他一些东西一起提交,所以它变得太麻烦了……这很好,直到其他人的 Xcode 决定要将它们改回 no明显的原因。 (我们的提交历史对此有很多诅咒。)

还有其他人看到这种行为吗? 这是我们的一台或多台开发人员 Mac 上的 Xcode 错误或配置问题吗? 我们在与 XIB 文件协作时看到了一些类似的行为,但故事板似乎更容易受到这种影响。

这不是错误,这是 Xcode 处理情节提要文件的方式的结果。 我正在为故事板文件(GitHub 链接)编写差异和合并程序,我花了数小时分析故事板文件逻辑以及 Xcode 如何处理它。 这是我发现的:

  • 为什么情节提要文件会发生奇怪的变化? Xcode 使用 NSXML API 将故事板文件解析为一些基于NSSet的逻辑树结构。 当 Xcode 需要写入更改时,它会根据逻辑树结构创建一个NSXMLDocument ,清除故事板文件并调用XMLDataWithOptions:再次填充文件。 因为集不保留其元素的顺序,所以即使是最细微的修改也可能会改变整个故事板 XML 文件。

  • 为什么类标签会随机消失或重新出现? <class>部分只不过是一个内部 Xcode 缓存。 Xcode 使用它来缓存有关类的信息。 缓存经常变化。 .h/.m类文件打开时添加元素,当 Xcode 怀疑它们已过时时删除它们(至少较旧的 Xcode 表现得像这样)。 当你保存故事板时,当前版本的缓存被转储,这就是<class>部分经常变化甚至消失的原因。

我没有对 Xcode 进行逆向工程; 我通过试验 Xcode 和故事板文件得出了这些观察结果。 尽管如此,我几乎 100% 肯定它是这样工作的。

结论

  • 缓存部分不重要; 您可以安全地忽略其中的任何更改。
  • 与您在所有论坛上可以找到的相反,合并故事板文件并不是一项复杂的任务。 例如,假设您更改了故事板文档中的MyController1视图控制器。 打开故事板文件,找到类似这样<viewController id=”ory-XY-OBM” sceneMemberID=”MyController1”> 您可以安全地只提交此部分中的更改,而忽略其他所有内容。 如果你改变了 segues 或约束,也提交任何里面有“ory-XY-OBM”东西。 简单的!

这是 XCode 4.5+ 中的一个错误,我希望它得到修复,是的,它是一个 PITA。

这是 Apple 的完整漏洞

如何避免 Xcode 无故编辑故事板文件?

这个问题可以通过在任何 Xcode 生成的文件上非常明智地使用git add -p来缓解,包括故事板、XIB、核心数据模型和项目文件,所有这些都遭受类似的瞬态修改,对实际没有影响接口/模型/项目。

我在故事板上看到的最常见的垃圾更改是系统版本号(如您所述)和<classes>部分的不断添加和删除,我从未见过遗漏这些部分会导致问题。 对于 XIB,它是<reference key="NSWindow"/>的添加和删除,它甚至不是 Cocoa Touch 中的一个类。 哇哦。

把它想象成大海:有涨潮也有退潮。 让它冲刷你。

啊。 而已。

您可以在暂存更改时忽略这些修改,重置垃圾更改并进行干净的提交。

从技术角度来看,我看到故事板相对于 XIB 的唯一优势是 Apple 尚未绝育 FileMerge 以拒绝合并冲突的故事板。 (FileMerge 曾经能够合并 XIB,但较新的版本打破了这一点。Thxxxx 伙计们!!!)

请在http://bugreporter.apple.com/提交有关所有这些问题的大量错误! 并且不要忘记在OpenRadar上创建条目。

在这里抛出另一个答案,因为这种情况已经大大改善。 表示 StoryBoard 的 XIB 文件的 XML 已大大简化。

我最近也硬着头皮开始使用Xcode中的接口来进行Source Control。 我已经在命令行上工作了很多年并且在那里很开心,但是界面很好,它可以让你拆分提交,如果你使用链接到提交的票务系统,这真的很重要。

不管怎样,我今天注意到情节提要板上发生了变化,内置差异显示它是文档标签 (systemVersion) 中的单个属性。 所以没什么大不了的。

我读过一些文章,其中有人说由于合并问题,SB 在他们的团队中是非法的。 完全疯狂。 它们太棒了,尤其是现在它们内置了智能自动布局,如果你不使用它们,你真的会错过。

知道为什么会发生这种疯狂是有帮助的,但对于那些相信让他们的项目没有警告并且只想快速而肮脏地让他们的项目恢复健康状态的人来说:

  1. 除非得到明确指示,否则不要做任何事情。

  2. 打开 Xcode 并创建一个新的故事板(Command+N > iOS > 用户界面 > 故事板)。 我假设您将其称为Storyboard.storyboard的默认名称。

  3. 打开 Xcode 违反的故事板。 我假设这是Base.lproj/Main.storyboard

  4. 选择并复制故事板上的所有内容(Command+A,然后是 Command+C)。

  5. 打开Storyboard.storyboard

  6. 将所有内容复制并粘贴到Storyboard.storyboard中。

  7. 关闭 Xcode。

  8. 打开终端并将目录更改为您的存储库。

  9. Main.storyboard替换为Storyboard.storyboard ( mv Storyboard.storyboard Base.lproj/Main.storyboard )。

  10. git add Base.lproj/Main.storyboard; git commit -m "Fix Xcode's insanity."

  11. 通过git checkout -- project.pbxproj忽略对project.pbxproj的更改。 如果你对文件进行git diff ,你会看到它刚刚添加了关于我们的临时故事板(不再存在)的信息。

  12. 备份打开 Xcode,看到警告已经消失。

  13. 呼吸。

在同一个故事板上工作不是问题。 但是在同一个视图控制器上工作会在拉/合并时产生冲突是很可怕的。 我们无法真正避免在大型团队的同一个视图控制器中工作。

好消息是,如果我们了解 xml 结构,大多数时候我们可以解决相同的 viewcontroller 冲突。 在团队合作时,我从未失败过合并这些。 假设您正在使用视图控制器。 您的视图当前是空白的。 请从源代码选项查看视图控制器的 xml 结构。

在此处输入图像描述

情节提要是受文档类型标记限制的 xml。 情节提要中的所有内容都包含在场景 sceneID= 标签中。 场景标签包含每个视图控制器。 这是基本的。

现在我们在视图上添加了一个 UILabel 和一个 UIButton。 还设置元素的自动布局。 现在它看起来像:

在此处输入图像描述

向视图控制器添加级别/按钮在视图的子视图标记内添加了一些新代码。 同样的事情将用于进一步的元素添加或任何 UI 更改。 仔细检查标签结构,这对于解决任何冲突非常重要。

现在我们在故事板名称 Homeviewcontroller 中添加另一个视图控制器。 添加一个新的视图控制器意味着它在场景标签下添加了一个新场景。 看这个:

在此处输入图像描述

此时,我们将随机更改结构并观察问题/警告。 我们更改第一个 viewcontroller 标签结束标记并保存文件。 现在运行它并查看警告。 从第 23 行创建的错误表示结束标记不正确。在第 23 行中,我们看到标签约束设置为没有结束标记。 那就是问题所在。 现在我们放置结束标记并构建项目。 设置完结束标签后,我们就可以成功查看storyboard了。

在此处输入图像描述

当遇到任何冲突警告时,请与您以前的来源进行比较并更改来源。 我们删除了旧的/冗余的代码,将新代码保留在正确的开始和结束标记中并修复问题。

[注意,我会在获得时间时用更多测试用例更新答案]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM