Storyboardy są raczej królewskim bólem z perspektywy przepływu pracy git, gdy współpracuje nad nimi wiele osób. Na przykład XML w pliku .storyboard ma swój początkowy <document>
znacznik toolsVersion
i systemVersion
atrybuty zmienione przez dowolną konfigurację, w której działa najnowszy manipulator plików. Synchronizacja wszystkich wersji Xcode wydaje się pomagać toolsVersion
, ale systemVersion
zmienia się bez względu na to, w zależności od konkretnej wersji Mac i / lub OS X, na której działa programista.
To idiotyczne, ale w większości nieszkodliwe. Martwi nas jednak to, że w innych przypadkach niektóre inne zmiany są automatycznie wprowadzane do scenorysu, po prostu otwierając je po pliku git pull
. Oznacza to, że Alicja wprowadza zmiany w scenorysie, zatwierdza je i wypycha do repozytorium. Następnie Bob pobiera zmiany Alice i otwiera scenorys, aby wprowadzić dalsze zmiany. W momencie, gdy otwiera scenorys, ikona pliku natychmiast zmienia się w zmodyfikowany, ale niezapisany stan, a ikona git status
pokazuje, że nastąpiła dowolna liczba dziwnych zmian. Wszystko to bez konieczności zmiany przez Boba lub samodzielnego zapisania pliku.
Najczęstszą automatyczną zmianą, którą widzimy, jest zniknięcie lub ponowne pojawienie się całej <classes>
hierarchii tagów pod koniec pliku storyboardu. Nie ustaliliśmy, co to powoduje. Możemy mieć kilka zlokalizowanych wersji scenorysu w różnych katalogach .lproj, a po otwarciu ich w programie Interface Builder hierarchia klas może zostać spontanicznie usunięta z niektórych i dodana do innych lub pozostawiona sama w niektórych. Powoduje to dużo hałasu git diff
, ale w rzeczywistości nie psuje żadnej funkcjonalności. Często będziemy selektywnie dodawać rzeczywiste zmiany, które wprowadziliśmy do indeksu gita, zatwierdzać je, a następnie po prostu odrzucać spontaniczne, bezsensowne<classes>
zmiany. Ma to na celu zachowanie niewielkich i ładnych zatwierdzeń, tak jak powinny. W końcu jednak staje się to zbyt trudne, ponieważ Xcode nieustannie odtwarza zmiany, a ktoś po prostu raguje je wraz z innymi rzeczami ... co jest w porządku, dopóki czyjś Xcode nie zdecyduje się na zmianę z powrotem na nie pozorny powód. (W naszej historii zmian jest wiele przekleństw).
Czy ktoś jeszcze widzi takie zachowanie? Czy jest to błąd Xcode lub problem z konfiguracją na co najmniej jednym z naszych komputerów Mac dla programistów? Widzieliśmy podobne zachowanie podczas współpracy z plikami XIB, ale scenorysy wydają się na to bardziej podatne.
źródło
Odpowiedzi:
To nie jest błąd, jest to konsekwencja tego, jak Xcode przetwarza pliki scenorysów. Piszę program do porównywania i scalania plików scenorysów (łącze GitHub) i spędziłem godziny na analizowaniu logiki plików scenorysów i sposobu, w jaki Xcode je przetwarza. Oto, co odkryłem:
Dlaczego w plikach scenorysu zachodzą dziwne zmiany? Xcode używa interfejsu API NSXML do analizowania plików scenorysu w
NSSet
logicznej strukturze drzewa. Kiedy Xcode musi zapisać zmiany, tworzy wNSXMLDocument
oparciu o logiczną strukturę drzewa, czyści plik storyboardu i wzywaXMLDataWithOptions:
do ponownego wypełnienia pliku. Ponieważ zestawy nie zachowują kolejności swoich elementów, nawet najmniejsza modyfikacja może zmienić cały plik XML storyboardu.Dlaczego tag klasy znika lub pojawia się losowo?
<class>
Sekcja nie jest niczym więcej niż wewnętrznej pamięci podręcznej Xcode. Xcode używa go do buforowania informacji o klasach. Pamięć podręczna często się zmienia. Elementy są dodawane, gdy.h/.m
pliki klas są otwierane i usuwane, gdy Xcode podejrzewa, że są nieaktualne (przynajmniej starsze Xcodes zachowują się w ten sposób). Po zapisaniu storyboardu aktualna wersja pamięci podręcznej jest zrzucana, dlatego<class>
sekcja często się zmienia lub nawet znika.Nie poddałem inżynierii wstecznej Xcode; Dokonałem tych obserwacji, eksperymentując z plikami Xcode i storyboardami. Mimo to jestem prawie w 100% pewien, że działa w ten sposób.
Wnioski :
MyController1
kontroler widoku w dokumencie serii ujęć. Otwórz plik storyboardu i znajdź coś takiego<viewController id=”ory-XY-OBM” sceneMemberID=”MyController1”>
. Możesz bezpiecznie zatwierdzać tylko zmiany w tej sekcji i ignorować wszystko inne. Jeśli zmieniłeś ścieżki lub ograniczenia, zatwierdź także wszystko, co ma w“ory-XY-OBM”
środku. Prosty!źródło
To jest błąd w XCode 4.5+, mam nadzieję, że zostanie naprawiony i tak, to PITA.
Oto pełny błąd w Apple
Jak uniknąć nieuzasadnionych zmian w plikach scenorysów w Xcode?
źródło
Ten problem można nieco złagodzić przez niezwykle rozsądne użycie
git add -p
dowolnego z wygenerowanych plików Xcode, w tym scenorysów, XIB, modeli danych podstawowych i plików projektów, z których wszystkie cierpią z powodu podobnych przejściowych modyfikacji, które nie mają wpływu na rzeczywisty interfejs / model / projekt.Najczęstsze śmieciowe zmiany, jakie widziałem w scenorysach, to numery wersji systemu (jak wspomniałeś) oraz ciągłe dodawanie i usuwanie
<classes>
sekcji, której pominięcie nigdy nie powodowało problemów. W przypadku XIB jest to dodawanie i usuwanie<reference key="NSWindow"/>
, co nie jest klasą w Cocoa Touch. Po prostu wow.Pomyśl o tym jak o morzu: jest zarówno przypływ, jak i odpływ. Niech cię obmyje.
Ahh. Otóż to.
Możesz zignorować te modyfikacje podczas przemieszczania zmian, zresetować niepotrzebne zmiany i dokonać czystego zatwierdzenia.
Jedyną zaletą, jaką widziałem w przypadku scenorysów nad XIB z technicznego punktu widzenia, jest to, że Apple nie zneutralizował jeszcze FileMerge, aby odmówić scalenia konfliktowych scenariuszy. (FileMerge mógł łączyć pliki XIB, ale nowsze wersje to zepsuły. Thxxxx guys 💜 !!!)
Prosimy o zgłaszanie wielu błędów dotyczących wszystkich tych problemów na stronie http://bugreporter.apple.com/ ! I nie zapomnij utworzyć wpisów w OpenRadar .
źródło
Dorzucam tutaj inną odpowiedź, ponieważ sytuacja znacznie się poprawiła. XML dla pliku XIB, który reprezentuje StoryBoard, został znacznie uproszczony.
Niedawno też ugryzłem kulę i zacząłem używać interfejsu w Xcode do kontroli źródła. Jestem w wierszu poleceń od lat i jestem szczęśliwy, ale interfejs jest fajny i pozwala na dzielenie zatwierdzeń, co jest naprawdę ważne, jeśli używasz systemu biletowego, który łączy się z zatwierdzeniami.
W każdym razie zauważyłem dzisiaj, że nastąpiła zmiana w scenorysie, a wbudowana różnica pokazała mi, że był to pojedynczy atrybut w tagu dokumentu (systemVersion). Więc nie jest to wielka sprawa.
Czytałem artykuły, w których ludzie twierdzą, że SB zostali wyjęci spod prawa w ich zespołach z powodu problemów z łączeniem. Całkowite szaleństwo. Są tak niesamowite, zwłaszcza teraz, gdy mają wbudowany inteligentny układ, więc naprawdę tracisz, jeśli ich nie używasz.
źródło
Warto wiedzieć, dlaczego dzieje się to szaleństwo, ale dla tych, którzy wierzą, że ich projekty są wolne od ostrzeżeń i chcą po prostu szybko i bezmyślnie przywrócić swoje projekty do zdrowego stanu:
Nie popełniaj niczego, dopóki nie zostanie to wyraźnie pouczone.
Otwórz Xcode i utwórz nową scenorys (Command + N> iOS> Interfejs użytkownika> Storyboard). Zakładam, że nazwiesz to domyślną nazwą
Storyboard.storyboard
.Otwórz scenorys, który naruszył Xcode. Zakładam, że tak
Base.lproj/Main.storyboard
.Zaznacz i skopiuj wszystko w serii ujęć (Command + A, a następnie Command + C).
Otwórz
Storyboard.storyboard
.Skopiuj i wklej wszystko do
Storyboard.storyboard
.Zamknij Xcode.
Otwórz terminal i zmień katalogi w swoim repozytorium.
Zastąpić
Main.storyboard
wStoryboard.storyboard
(mv Storyboard.storyboard Base.lproj/Main.storyboard
).git add Base.lproj/Main.storyboard; git commit -m "Fix Xcode's insanity."
Zignoruj zmiany w
project.pbxproj
za pośrednictwemgit checkout -- project.pbxproj
. Jeśli znajdzieszgit diff
plik, zobaczysz, że właśnie dodał informacje o naszej tymczasowej planszy (która już nie istnieje).Otwórz kopię zapasową Xcode i zobacz, że ostrzeżenia zniknęły.
Oddychać.
źródło
Praca nad tym samym scenorysem nie stanowi problemu. Ale praca z tym samym kontrolerem widoku, który tworzy konflikty przy ściąganiu / scalaniu, jest przerażająca. nie możemy uniknąć pracy w tym samym kontrolerze widoku dla dużego zespołu.
Dobrze, że w większości przypadków możemy naprawić te same konflikty kontrolera widoku, jeśli zrozumiemy strukturę xml. Nigdy nie zawiodłem się w ich połączeniu podczas pracy w zespole. Załóżmy, że pracujesz z kontrolerem widoku. Twój widok jest obecnie pusty. Proszę spojrzeć na strukturę XML Viewcontrollera z opcji kodu źródłowego.
Storyboard to XML ograniczony tagiem typu dokumentu. Wszystko w serii ujęć zawiera tag sceny sceneID =. tag sceny zawiera wszystkie kontrolery widoku. To podstawa.
Teraz dodaliśmy do widoku UILabel i UIButton. Ustaw także autoukład elementów. Teraz wygląda to tak:
Dodanie poziomu / przycisku do kontrolera widoku dodało nowy kod wewnątrz tagu subview widoku. To samo dotyczy dalszego dodawania elementów lub zmian interfejsu użytkownika. Dokładnie sprawdź strukturę tagów, która jest naprawdę ważna, aby naprawić wszelkie konflikty.
Teraz dodajemy kolejny kontroler widoku w nazwie scenorysu Homeviewcontroller. Dodanie nowego kontrolera widoku oznacza dodanie nowej sceny pod tagiem scen. Spójrz na to:
W tym momencie losowo zmienimy strukturę i będziemy obserwować problemy / ostrzeżenia. Zmieniamy pierwszy tag końcowy etykiety viewcontroller i zapisujemy plik. Teraz uruchom go i spójrz na ostrzeżenie. Błąd mówi, że znacznik końcowy jest nieprawidłowy, który został utworzony z wiersza 23. W wierszu 23 widzimy, że ograniczenia etykiety są ustawione bez znacznika końcowego. To jest problem. Teraz umieszczamy tag końcowy i budujemy projekt. Po ustawieniu tagu końcowego możemy pomyślnie wyświetlić storyboard.
Gdy napotkasz jakiekolwiek ostrzeżenie o konfliktach, porównaj z poprzednim źródłem i zmienia źródło. Usuwamy stary / nadmiarowy kod, zachowujemy nowy kod z odpowiednim początkiem i końcem tagu i naprawiamy wszystko.
[Uwaga: zaktualizuję odpowiedź o więcej przypadków testowych, gdy otrzymam czasy]
źródło