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

当多人合作的时候,故事板就是git工作stream程中的王室之痛。 例如,.storyboard文件中的XML有其最初的<document>标签的toolsVersionsystemVersion属性被最近的文件操纵器正在运行的任何configuration所改变。 同步每个人的Xcode版本似乎有助于toolsVersion ,但systemVersion会根据开发人员运行的特定的Mac和/或OS X版本进行更改。

这是愚蠢的,但大多是无害的。 但是,我们担心的是在其他时候,一些其他的变化是通过在git pull之后打开它们而自动作出的。 也就是说,Alice对故事板进行更改,提交并将其推送到存储库。 然后鲍勃拉动爱丽丝的变化,打开故事板进行进一步的修改。 当他打开故事板时,文件图标立即变为已修改但未保存的状态,并且git status显示发生了任意数量的奇怪更改。 所有这些没有鲍勃改变了任何东西或自己保存文件。

我们看到的最常见的自动更改是在故事板文件结尾附近的整个<classes>标签层次的消失或再现。 我们还没有弄清楚是什么原因造成的。 我们可能在各种.lproj目录中有几个本地化版本的故事板,当在Interface Builder中打开它时,类层次结构可能会自发地从某些目录中删除并添加到其他目录中,或者在某些情况下单独保留。 这在git diff导致了很多噪音,但是它并没有打破任何function。 我们经常会有select地将我们所做的实际改变添加到git的索引中,提交它们,然后放弃自发的,无意义的<classes>改变。 这是保持承诺小而美好,因为他们应该是。 但最终,Xcode一直在重新做这些改变,这让人感到非常烦恼,而且有些人只是把它们和其他一些东西一起提交给他们,直到别人的Xcode决定要把他们改回来明显的原因。 (我们的提交历史有很多骂这个。)

有没有人看到这种行为? 这是一个Xcode错误还是一个或多个我们的开发人员的Mac上的configuration问题? 在与XIB文件合作时,我们已经看到了一些类似的行为,但是故事板似乎更容易受此影响。

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

  • 为什么在故事板文件中出现奇怪的变化? Xcode使用NSXML API将故事板文件parsing为基于NSSet的逻辑树结构。 当Xcode需要编写更改时,将创build一个基于逻辑树结构的NSXMLDocument ,清除故事板文件并调用XMLDataWithOptions:以再次填充文件。 由于集合不保留元素的顺序,即使稍作修改也可能会更改整个storyboard XML文件。

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

我没有反向工程的Xcode; 我通过对Xcode和storyboard文件的实验来做出这些观察。 尽pipe如此,我几乎100%肯定它是这样工作的。

结论

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

这是XCode 4.5+中的一个错误,我希望它能被修复,而且它是一个PITA。

这是苹果公司的完整错误

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

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

我在故事板上看到的最常见的垃圾变化是系统版本号(正如你所提到的)以及<classes>部分的不断添加和删除,以及我从未见过的遗漏问题。 对于XIB,它是<reference key="NSWindow"/>的添加和删除,它甚至不是Cocoa Touch中的一个类。 哇哇!

把它想象成海:既有高潮又有低潮。 让它冲刷你。

啊。 而已。

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

从技术的angular度来看,我看过XIB的故事板的一个优点是苹果还没有让FileMerge去拒绝合并冲突的故事板。 (FileMerge曾经能够合并XIB,但新版本打破了这一点。Thxxxx家伙💜!!!)

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

因为这种情况已经大大改善,所以在这里再作一个回答。 表示StoryBoard的XIB文件的XML已经大大简化了。

我最近也咬了一颗子弹,并开始使用Xcode中的接口到源代码pipe理。 我已经在命令行上工作了很多年,并且很开心,但是界面很好,它可以让你分割提交,如果你使用一个连接到提交的票务系统,这是非常重要的。

无论如何,我今天注意到故事板上有一个变化,内置的diff显示了它是文档标签(systemVersion)中的单个属性。 所以没什么大不了的

我已经阅读过文章,人们说由于合并问题,SB在他们的球队被禁止。 总的疯狂。 他们太棒了,尤其是现在他们内置了智能的自动布局function,如果你不使用它们,你真的错过了。

知道为什么会发生这种疯狂是有帮助的,但是对于那些相信让他们的项目不受警告,只是想要一个快速又脏兮兮的项目来让他们的项目恢复到健康状态的人来说是很有帮助的:

  1. 在明确指示之前不要做任何事情。

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

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

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

  5. 打开Storyboard.storyboard

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

  7. closuresXcode。

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

  9. Storyboard.storyboardreplaceMain.storyboardmv Storyboard.storyboard Base.lproj/Main.storyboard )。

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

  11. 忽略通过git checkout -- project.pbxprojproject.pbxproj的更改。 如果你使用不同的文件,你会发现它刚刚添加了关于我们的临时故事板(不再存在)的信息。

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

  13. 呼吸。