1. ホーム
  2. ios

[解決済み] Xcode が未修正のストーリーボードと XIB ファイルを変更する。

2022-06-16 17:32:27

質問

ストーリーボードは、複数の人が共同作業する場合、gitワークフローの観点からかなり苦痛です。例えば、.storyboard ファイル内の XML には、その始まりである <document> タグの toolsVersionsystemVersion 属性は、最新のファイルマニピュレータがたまたま実行しているどんな設定によっても変更されます。みんなの Xcode バージョンを正確に同期させると toolsVersion には役立ちますが systemVersion は、開発者が実行している特定の Mac および/または OS X のバージョンによって、何があっても変化します。

これはバカバカしいことですが、ほとんど無害です。しかし、私たちが心配なのは、あるときは、ストーリーボードを git pull . つまり、アリスがストーリーボードに変更を加え、コミットしてリポジトリにプッシュします。次にボブはアリスの変更を引き出して、さらに変更を加えるためにストーリーボードを開きます。彼がストーリーボードを開いた瞬間、ファイルのアイコンはすぐに修正済みだが未保存の状態になり git status が表示され、奇妙な変更がいくつも発生していることがわかります。これらはすべて、Bob 自身が何も変更せず、ファイルを保存することなく行われています。

私たちが見ている最も一般的な自動化された変更点は、全体の <classes> タグの階層が消えたり現れたりすることです。何が原因なのかはまだわかっていません。ストーリーボードのいくつかのローカライズバージョンが様々な.lprojディレクトリにあり、Interface Builderでそれらを開くと、クラス階層が自然に削除されて他のものに追加されたり、あるものはそのままにされたりすることがあります。このため git diff に大きなノイズを発生させますが、実際には何の機能性も損ないません。私たちはしばしば、実際に行った変更を git のインデックスに選択的に追加し、それらをコミットして、自然発生的で無意味な <classes> のような変更は破棄します。これは、コミットの規模を小さくして、あるべき姿に保つためです。しかし最終的には、Xcodeが変更をやり直したり、誰かが他のものと一緒にラグコミットしたりするため、悩むことが多くなってしまいます...。(私たちのコミット履歴には、この件に関する悪態がたくさんあります)。

他にこの動作を見た人はいますか?これは Xcode のバグでしょうか、それとも開発者の Mac の 1 台または複数台の設定の問題でしょうか? XIB ファイルで共同作業しているときに、いくつかの同様の動作を見たことがありますが、ストーリーボードはより影響を受けやすいようです。

解決方法は?

これはバグではなく、Xcodeがストーリーボード・ファイルを処理する方法の結果です。 私はストーリーボード ファイル用の diff およびマージ プログラムを書いています。 (GitHub リンク) で、ストーリーボード・ファイルのロジックとXcodeがそれをどのように処理するかを分析するのに何時間も費やしました。これは私が発見したことです。

  • ストーリーボード ファイルで奇妙な変更が起こるのはなぜですか。 Xcode は NSXML API を使用して、ストーリーボード・ファイルを解析して、いくつかの NSSet -ベースの論理ツリー構造に変換します。Xcode が変更を書き込む必要があるとき、それは NSXMLDocument を作成し、storyboard ファイルをクリアして XMLDataWithOptions: を呼び出して再びファイルを埋める。セットはその要素の順序を保持しないので、わずかな修正でもストーリーボードXMLファイル全体を変更する可能性があります。

  • classタグがランダムに消えたり現れたりするのはなぜですか? その <class> セクションは、Xcodeの内部キャッシュに過ぎません。Xcodeは、クラスに関する情報をキャッシュするためにこれを使用します。キャッシュは頻繁に変更されます。要素が追加されるのは、クラス .h/.m ファイルが開かれたときに追加され、Xcodeがそれらが古いと疑ったときに削除されます(少なくとも古いXcodeはこのように動作します)。ストーリーボードを保存すると 現在の バージョンのキャッシュがダンプされ、そのため <class> セクションがしばしば変化したり消えたりするのはそのためです。

私は Xcode をリバースエンジニアリングしたわけではありません。Xcode とストーリーボード ファイルで実験することによって、これらの観察を行いました。とはいえ、この方法で動作することは、ほぼ 100%確実です。

結論 :

  • キャッシュセクションは重要ではないので、どのような変更も無視してかまいません。
  • すべてのフォーラムで見かけるのとは反対に、ストーリーボード ファイルのマージは複雑な作業ではありません。たとえば、あなたが MyController1 ビューコントローラを変更したとします。ストーリーボード・ファイルを開くと、次のようなものがあります。 <viewController id=”ory-XY-OBM” sceneMemberID=”MyController1”> . このセクションの変更だけを安全にコミットし、他のすべてを無視することができます。セグメンテーションやコンストレイントを変更した場合は、以下の部分もコミットしてください。 “ory-XY-OBM” の中にあるものもコミットしてください。シンプル!