Xcode изменяет неизмененную раскадровку и файлы XIB


132

Раскадровка - это скорее проблема с точки зрения рабочего процесса git, когда над ними работают несколько человек. Например, начальный <document>тег toolsVersionи systemVersionатрибуты XML в файле .storyboard изменяются в зависимости от конфигурации, в которой работает последний файловый манипулятор. Кажется, что синхронизация всех версий Xcode точно помогает toolsVersion, но systemVersionменяется, несмотря ни на что, в зависимости от конкретной версии Mac и / или OS X, которую использует разработчик.

Это идиотизм, но в основном безобидный. Однако нас беспокоит то, что в других случаях некоторые другие изменения автоматически вносятся в раскадровку, просто открывая их после файла git pull. Другими словами, Алиса вносит изменения в раскадровку, фиксирует и отправляет их в репозиторий. Затем Боб извлекает изменения Алисы и открывает раскадровку, чтобы внести дальнейшие изменения. В тот момент, когда он открывает раскадровку, значок файла сразу меняется на измененное, но несохраненное состояние, и git statusпоказывает, что произошло любое количество странных изменений. И все это без того, чтобы Боб ничего изменил или сохранил файл сам.

Наиболее частое автоматическое изменение, которое мы наблюдаем, - это исчезновение или повторное появление всей <classes>иерархии тегов ближе к концу файла раскадровки. Мы не выяснили, что вызывает это. У нас может быть несколько локализованных версий раскадровки в различных каталогах .lproj, и при их открытии внутри Interface Builder иерархия классов может самопроизвольно удаляться из одних и добавляться в другие или оставаться в покое в некоторых. Это вызывает много шума git diff, но на самом деле не нарушает никаких функций. Мы часто выборочно добавляем фактические изменения, которые мы внесли в индекс git, фиксируем их, а затем просто отбрасываем спонтанные, бессмысленные<classes>меняется. Это сделано для того, чтобы коммиты оставались маленькими и красивыми, какими они должны быть. В конце концов, однако, становится слишком много, чтобы возиться с этим, поскольку Xcode продолжает повторно вносить изменения, а кто-то просто в ярости передает их вместе с некоторыми другими вещами ... и это нормально, пока кто-то другой Xcode не решит изменить их обратно без очевидная причина. (Наша история коммитов много ругается по этому поводу.)

Кто-нибудь еще видит такое поведение? Это ошибка Xcode или проблема с конфигурацией на одном или нескольких компьютерах Mac для разработчиков? Мы наблюдали подобное поведение при совместной работе с файлами XIB, но раскадровки кажутся более восприимчивыми к этому.


Действительно, проекты Xcode и Git не очень хорошо работают вместе. Я не думаю, что вы можете избежать этого беспорядка, кроме как отбросить ненужные изменения - это почти всегда изменения файлов проекта для меня и других файлов xml, я уверен, что я не менял. Буду рад, если найдется какое-нибудь «решение». Мне нравится Perforce за удобную функцию блокировки, не позволяющую Xcode слишком сильно изменять, что, вероятно, можно было бы сделать вручную для файлов, которые вы не собираетесь изменять, а только для просмотра.
A-Live

3
Не стоит использовать раскадровки с git или чем-то еще. Они не предназначены для фиксации. Мы сдались и выбрали .xib, который тоже не так хорош, но, по крайней мере, он детализирован.
ahwulf

Мы обнаружили, что раскадровки довольно удобны для довольно многих вещей, хотя часто бывает необходимо смешивать их с XIB. Если эта ошибка когда-нибудь будет исправлена, мы будем счастливы работать с ними большую часть времени.
JK Laiho

Я просто должен прокомментировать комментарий Ахвульфа: что, черт возьми, вы имеете в виду, они не настроены дружелюбно? Это XML / текстовые файлы, которые настолько удобны для коммитов, насколько это возможно. И у меня не было проблем с раскадровкой и системой управления версиями, единственная проблема, конечно, в том, что xcode иногда удаляет тег <classes>, а затем считывает его позже, но вы можете легко это увидеть, если посмотрите на изменения с помощью графический интерфейс git или git -p или эквивалент для любого dvcs. У меня никогда не случалось такого с файлом .pbxproj в качестве fyi.
mgrandi

Я не могу понять, почему xcode помещает блоки классов внутри раскадровки, если он может просто сгенерировать эти блоки, прочитав файлы классов? они что-то вроде "тайника"? если да, то они должны быть помещены в файл classes.cache, чтобы мы могли исключить его из управления версиями ...
hariseldon78 09

Ответы:


78

Это не ошибка, это следствие того, как Xcode обрабатывает файлы раскадровки. Я пишу программу сравнения и слияния файлов раскадровки (ссылка на GitHub), и я провел часы, анализируя логику файлов раскадровки и то, как Xcode ее обрабатывает. Вот что я обнаружил:

  • Почему в файлах раскадровки происходят странные изменения? Xcode использует NSXML API для синтаксического анализа файлов раскадровки в некоторую NSSetлогическую древовидную структуру. Когда Xcode необходимо записать изменения, он создает NSXMLDocumentфайл на основе логической древовидной структуры, очищает файл раскадровки и вызывает XMLDataWithOptions:повторное заполнение файла. Поскольку наборы не сохраняют порядок своих элементов, даже малейшее изменение может изменить весь XML-файл раскадровки.

  • Почему тег класса исчезает или появляется снова случайно? <class>Раздел не более , чем внутренний кэш Xcode. Xcode использует его для кэширования информации о классах. Кеш часто меняется. Элементы добавляются при .h/.mоткрытии файлов классов и удаляются, когда Xcode подозревает, что они устарели (по крайней мере, более старые Xcodes ведут себя так). Когда вы сохраняете раскадровку, текущая версия кеша выгружается, поэтому <class>раздел часто меняется или даже исчезает.

Я не перепроектировал Xcode; Я сделал эти наблюдения, экспериментируя с Xcode и файлами раскадровки. Тем не менее, я почти на 100% уверен, что так работает.

Выводы :

  • Раздел кеша не важен; вы можете спокойно игнорировать любые его изменения.
  • В отличие от того, что вы можете найти на всех форумах, объединение файлов раскадровки не является сложной задачей. Например, предположим, что вы изменили MyController1контроллер представления в документе раскадровки. Откройте файл раскадровки и найдите что-то вроде этого <viewController id=”ory-XY-OBM” sceneMemberID=”MyController1”>. Вы можете безопасно фиксировать только изменения в этом разделе и игнорировать все остальное. Если вы изменили сегменты или ограничения, также зафиксируйте все, что находится “ory-XY-OBM”внутри. Просто!

9
Любое обновление инструмента xcode diff / merge? Похоже, это будет очень полезно для этого сообщества.
Тони

1
Вы можете скачать приложение с моей веб-страницы (см. Профиль). Приложение на 100% бесплатное.
Марцин Олавски

1
Для меня максимальное количество раскадровок == с использованием XIB. Если вы хотите, чтобы все было нарезано, проще и лучше использовать XIB
Марцин Олавски,

7
«Я не перепроектировал Xcode; я сделал эти наблюдения, экспериментируя с Xcode и файлами раскадровки». То есть (мелкий) реверс-инжиниринг, и это круто . :-)
Константино Царухас

13
«Это не ошибка, это следствие того, как Xcode обрабатывает файлы раскадровки». С уважением, вторая половина этого предложения никоим образом не объясняет и не рационализирует первую. Я бы изменил его следующим образом: «Это ошибка. Это [к сожалению, нерешенное и очень раздражающее] последствие того, как XCode обрабатывает файлы .xib». Начиная с XCode 5.x по 6.2 (сегодня 150311) .xib-файлы, никаким образом не измененные разработчиком, а просто просматриваемые в IB, претерпевают безвозмездные изменения xml. Это грубая ошибка, влияющая на производительность. Такие ответы, как «NBD, раздайте только куски в git», лишают меня дара речи.
cweekly

18

Это ошибка в XCode 4.5+, я надеюсь, что она будет исправлена, и да, это PITA.

Вот полная ошибка в Apple

Как избежать необоснованного редактирования файлов раскадровки в Xcode?


1
То же самое в 4.6. Может это не ошибка.
Thromordyn

4.6.3 все еще есть. Не могу сказать, что раскадровка / xibs когда-либо работали хорошо
houbysoft

1
«Это не ошибка, это особенность»: -S
MrTJ

Нет никаких доказательств того, что это ошибка - досадно, да, но это может быть просто то, как Xcode делает вещи
Томас Уотсон

1
7.0.1 не внес никаких изменений в это.
Андрис Залитис

11

Эту проблему можно несколько смягчить путем чрезвычайно разумного использования git add -pлюбого из файлов, сгенерированных Xcode, включая раскадровки, XIB, модели Core Data и файлы проекта, все из которых страдают от аналогичных временных модификаций, которые не влияют на фактический интерфейс / модель / проект.

Наиболее распространенные нежелательные изменения, которые я видел на раскадровках, - это номера версий системы (как вы упомянули) и постоянное добавление и удаление <classes>раздела, упущение которых, как я никогда не видел, вызывает проблемы. Для XIB это добавление и удаление<reference key="NSWindow"/> , что даже не является классом в Cocoa Touch. Просто вау.

Думайте об этом как о море: есть и прилив, и отлив. Пусть омывает тебя.

Ааа. Вот и все.

Вы можете игнорировать эти модификации при постановке ваших изменений, сбросить ненужные изменения и сделать чистую фиксацию.

Единственное преимущество, которое я видел у раскадровок перед XIB с технической точки зрения, заключается в том, что Apple еще не кастрировала FileMerge, чтобы отказаться от объединения конфликтующих раскадровок. (Раньше FileMerge мог объединять XIB, но в новых версиях это сломалось. Thxxxx, ребята 💜 !!!)

Пожалуйста, сообщайте об ошибках обо всех этих проблемах на http://bugreporter.apple.com/ ! И не забывайте создавать записи на OpenRadar .


6

Бросаю здесь другой ответ, потому что эта ситуация значительно улучшилась. XML для файла XIB, представляющего StoryBoard, был значительно упрощен.

Я также недавно укусил пулю и начал использовать интерфейс в Xcode для управления версиями. Я много лет работаю с командной строкой и счастлив там, но интерфейс приятный и позволяет разделять коммиты, что действительно важно, если вы используете систему тикетов, которая ссылается на коммиты.

В любом случае, сегодня я заметил изменение в раскадровке, и встроенный diff показал мне, что это единственный атрибут в теге документа (systemVersion). Так что ничего страшного.

Я читал статьи, в которых люди говорят, что SB были объявлены вне закона в их командах из-за проблем слияния. Полное безумие Они настолько потрясающие, особенно теперь, когда в них встроена интеллектуальная автоматическая раскладка, вы действительно упускаете из виду, если не используете их.


3

Полезно знать, почему происходит это безумие, но для тех, кто верит в то, что в их проектах нет предупреждений, и кто просто хочет быстро и грязно вернуть свои проекты в нормальное состояние:

  1. Не совершайте ничего, пока не получите явных указаний.

  2. Откройте Xcode и создайте новую раскадровку (Command + N> iOS> Пользовательский интерфейс> Раскадровка). Я предполагаю, что вы называете это именем по умолчанию Storyboard.storyboard.

  3. Откройте раскадровку, которую нарушил Xcode. Я предполагаю, что это так Base.lproj/Main.storyboard.

  4. Выделите и скопируйте все на раскадровке (Command + A, затем Command + C).

  5. Open 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. Пропустите изменения project.pbxprojчерез git checkout -- project.pbxproj. Если вы git diffоткроете файл, вы увидите, что он только что добавил информацию о нашей временной раскадровке (которой больше нет).

  12. Откройте резервную копию Xcode и убедитесь, что предупреждения исчезли.

  13. Вдох.


0

Работа над одной раскадровкой - не проблема. Но работа с одним и тем же контроллером представления, который создает конфликты при извлечении / слиянии, пугает. мы действительно не можем избежать этого, работая в одном viewcontroller для большой команды.

Хорошо, что большую часть времени мы можем исправить одни и те же конфликты контроллера представления, если понимаем структуру xml. Я ни разу не упустил возможности объединить их, работая в команде. Предположим, вы работаете с контроллером просмотра. Ваш вид в настоящее время пуст. Пожалуйста, посмотрите на xml-структуру viewcontroller из опции исходного кода.

введите описание изображения здесь

Раскадровка - это xml, ограниченный тегом типа документа. Все в раскадровке содержится в теге sceneID =. Тег сцены содержит все контроллеры просмотра. Это основное.

Теперь мы добавили в представление UILabel и UIButton. Также установите автоматическое размещение элементов. Теперь это выглядит так:

введите описание изображения здесь

Добавление уровня / кнопки в viewcontroller добавило некоторый новый код внутри тега subview представления. То же самое касается дальнейшего добавления элементов или любых изменений пользовательского интерфейса. Тщательно проверьте структуру тегов, что действительно важно для устранения любых конфликтов.

Теперь мы добавляем еще один viewcontroller в имя раскадровки Homeviewcontroller. Добавление нового контроллера просмотра означает, что он добавляет новую сцену под тегом сцен. Посмотри на это:

введите описание изображения здесь

На этом этапе мы случайным образом изменим структуру и рассмотрим проблемы / предупреждения. Мы меняем конечный тег метки первого контроллера просмотра и сохраняем файл. Теперь запустите его и посмотрите предупреждение. Ошибка говорит о том, что конечный тег неверен, который создан из строки 23. В строке 23 мы видим, что ограничения метки установлены без конечного тега. Это проблема. Теперь ставим закрывающий тег и строим проект. После установки конечного тега мы можем успешно просмотреть раскадровку.

введите описание изображения здесь

Если вы столкнетесь с каким-либо предупреждением о конфликтах, сравните с вашим предыдущим источником и источником изменений. Мы удаляем старый / избыточный код, оставляем новый код с правильным началом и концом тега и исправляем ошибки.

[NB, я дополню ответ еще несколькими тестовыми случаями, когда получу время]

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.