Xcode更改未修改的情节提要和XIB文件


132

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

这是愚蠢的,但大部分无害。不过,令我们担心的是,有时在故事板之后,只要打开,它们就会自动进行其他更改git pull。也就是说,爱丽丝对情节提要板进行更改,然后提交并推送到存储库。然后,Bob拉出Alice的更改,并打开情节提要进行进一步更改。他打开情节提要板的那一刻,文件图标立即变为已修改但未保存的状态,并且git status表明发生了许多奇怪的更改。所有这些都无需Bob更改任何内容或自己保存文件。

我们看到的最常见的自动更改是,<classes>故事板文件结尾附近的整个标签层次消失或重新出现。我们还没有弄清楚是什么原因造成的。我们可能在不同的.lproj目录中有多个故事板的本地化版本,并且在Interface Builder中打开它们时,类层次结构可能会自发地从某些类中删除并添加到其他类中,或者单独留在某些类中。这会在中引起很多噪音git diff,但实际上并没有破坏任何功能。我们通常会选择性地将实际所做的更改添加到git的索引中,提交这些更改,然后仅丢弃自发的,毫无意义的<classes>变化。这是为了使提交尽可能小巧,美观。最终,尽管如此,由于Xcode不断重复所做的更改,这变得太麻烦了,而有人只是将它们与其他内容一起进行了批处理……这很好,直到其他人的Xcode决定不做任何更改。明显的原因。(我们的提交历史对此有很多誓言。)

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


确实,Xcode项目和Git在一起做得不好。我认为除了丢弃不必要的更改外,您无法避免其他麻烦-几乎总是我和其他xml文件更改了我确定我没有更改的项目文件。如有任何“解决方案”,我们将很高兴。我喜欢Perforce,因为它具有便捷的锁定功能,不允许Xcode进行太多更改,这可能是手动完成的,这些文件不会更改,而仅用于查看。
A-Live

3
不值得将本故事板与git或其他任何东西一起使用。它们的设计目的不是友好的。我们放弃了.xib,虽然它也不是那么好,但至少是颗粒状的。
ahwulf 2012年

我们发现故事板实际上可以很好地处理很多事情,尽管通常有必要将它们与XIB混合使用。如果此错误得以解决,我们将非常乐意与他们合作。
JK Laiho 2012年

我只需要评论ahwulf的评论:在世界上,这意味着他们不友好吗?它们是XML /文本文件,多数民众赞成在提交时尽可能友好。而且我对情节提要和版本控制系统没有“问题”,唯一的问题当然是xcode有时会删除<classes>标记,然后在以后读取它,但是如果您查看带有的更改,则可以很容易地看到这一点。 git GUI或git -p或等效的dvcs。我从来没有发生过这种情况。.pbxproj文件仅供参考。
mgrandi

我不明白,如果xcode只能通过读取类文件生成那些块,为什么xcode会将这些类块放在情节提要中?他们是一种“缓存”吗?如果是这样,则应将它们放在classes.cache文件中,以便我们将其从版本控制中排除...
hariseldon78 2013年

Answers:


78

这不是错误,这是Xcode处理情节提要文件的结果。我正在为情节提要文件(GitHub链接)编写一个diff和merge程序,并且花了数小时来分析情节提要文件逻辑以及Xcode如何对其进行处理。这是我发现的:

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

  • 为什么班级标签会随机消失或重新出现?<class>部分仅是内部Xcode缓存。Xcode使用它来缓存有关类的信息。缓存经常更改。当.h/.m打开类文件时添加元素,如果Xcode怀疑它们已过时,则将其删除(至少旧的Xcode的行为是这样的)。当您保存情节提要时,当前版本的缓存将被转储,这就是为什么该<class>节经常更改甚至消失的原因。

我没有对Xcode进行反向工程;我通过试验Xcode和Storyboard文件进行了观察。不过,我几乎100%确信它会以这种方式工作。

结论

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

9
关于xcode差异/合并工具的任何更新?听起来这对这个社区将非常有用。
Tony

1
您可以从我的网页上获取该应用程序(请参阅个人资料)。该应用程序是100%免费的。
Marcin Olawski 2013年

1
对我而言,使用XIB尽可能拆分故事板==。如果你想拥有的一切切片,它更容易和更好地使用XIBs
马辛Olawski

7
“我还没有对Xcode进行反向工程;我通过试验Xcode和情节提要文件进行了观察。” 那(浅)反向工程,而且很酷。:-)
Constantino Tsarouhas 2014年

13
“这不是错误,这是Xcode处理情节提要文件的结果。”顺便说一句,这句话的后半部分决不能解释或合理化前一个。我将其修改为:“这是一个错误。这是XCode处理.xib文件的方式(不幸的是,尚未解决且非常令人讨厌)”。从XCode 5.x到6.2(今天为150311),开发人员未修改任何.xib文件,仅在IB中进行了查看,它们遭受了无用的xml更改。这是一个严重的错误,会影响生产率。诸如“ NBD,只用git处理大块”之类的回答让我无语。
cweekly 2015年

18

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

这是Apple的完整错误

如何避免对故事板文件进行无意的Xcode编辑?


1
4.6中也是如此。也许不是错误。
Thromordyn13年

4.6.3仍然拥有它。不能说分镜脚本/ xib曾经工作得很好
houbysoft

1
“这不是错误,而是功能”:-S
MrTJ

没有证据表明这是一个错误-是一个烦人,但是可能只是Xcode的填充方式
Thomas Watson

1
7.0.1尚未对此进行任何更改。
Andris Zalitis

11

可以通过非常明智地使用git add -pXcode生成的任何文件(包括情节提要,XIB,Core Data模型和项目文件)在某种程度上缓解此问题,所有这些文件都经历了类似的短暂修改,这些修改对实际界面/模型/没有影响。项目。

我在情节提要板上看到的最常见的垃圾更改是系统版本号(如您所述)以及该节的不断添加和删除<classes>,而我从未见过的遗漏会导致问题。对于XIB,它是添加和删除<reference key="NSWindow"/>,甚至在Cocoa Touch中都不是一类。哇

像大海一样思考:潮高潮低。让它洗净你。

啊 而已。

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

从技术的角度来看,与XIB相比,我对情节提要板看到的唯一优势是,苹果公司尚未绝不FileMerge拒绝合并有冲突的情节提要板。(FileMerge曾经能够合并XIB,但是较新的版本打破了这一点。Thxxxx💜!)

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


6

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

最近,我也咬了一下子,开始使用Xcode中的界面进行源代码管理。我已经在命令行上使用多年了,但在那里过得很愉快,但是界面很好,它可以让您拆分提交,如果您使用链接到提交的票证系统,这真的很重要。

无论如何,我今天注意到情节提要板上有一个更改,并且内置的差异显示了它是文档标签(systemVersion)中的单个属性。所以没什么大不了的。

我读过一些文章,有人说由于合并问题,SB被禁止在其团队中使用。完全疯狂。它们是如此惊人,特别是现在它们内置了智能自动布局,如果不使用它们,您真的会错过。


3

知道为什么会发生这种精神错乱是有帮助的,但是对于那些相信自己的项目不会受到警告并且只想快速又肮脏地使他们的项目恢复到健康状态的人来说,这是有帮助的:

  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.storyboardStoryboard.storyboardmv Storyboard.storyboard Base.lproj/Main.storyboard)。

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

  11. 忽略对project.pbxprojvia 的更改git checkout -- project.pbxproj。如果您使用的git diff是文件,则会看到该文件刚刚添加了有关我们的临时情节提要(不再存在)的信息。

  12. 备份打开Xcode,然后查看警告已消失。

  13. 呼吸。


0

在同一情节提要板上工作不是问题。但是在同一个viewcontroller上进行操作会在拉/合并时产生冲突,这令人恐惧。我们真的不能避免为大型团队在同一ViewController中工作。

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

在此处输入图片说明

故事板是xml,由文档类型标签界定。情节提要中的所有内容都包含在场景sceneID =标签中。场景标签包含每个ViewController。多数民众赞成在最基本的。

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

在此处输入图片说明

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

现在,我们在情节提要中添加另一个viewcontroller名称Homeviewcontroller。添加一个新的viewcontroller意味着它将在scenes标签下添加一个新场景。看这个:

在此处输入图片说明

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

在此处输入图片说明

遇到任何冲突警告时,请与您以前的来源进行比较并更改来源。我们删除了旧的/多余的代码,使用正确的标签start-end保留了新代码,并进行了修复。

[注意,获取时间后,我将使用更多测试用例更新答案]

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.