5

これらすべての「NSOrderedSet は後で追加されたため、他のコンポーネントとうまく連携する必要はありません」というバグは私を夢中にさせます…</p>

( https://twitter.com/kubanekl/status/413447039855640576 )

2 つのマネージド オブジェクトと、それらの間の順序付けられた 1:N の関係がありますNSOrderedSetNSArrayControllerが提供する機能 (選択管理、コンテンツのバインディング、 のようなビューへのバインディング) から利益を得るために、を使用してこの関係を管理したいと考えていますNSTableView

NSOrderedSetは のサブクラスではないため、NSSetcontentSetバインディングはNSArrayControllerその関係では機能しません。次のスレッドを見つけて、そこに記載されている提案を実装しようとしました。

最初の提案はcontentArray、順序付けられたセットをオンザフライで配列に変換するためにバインディングと値トランスフォーマーを使用することです。このソリューションの問題は、変更が行われるたびにコンテンツが再割り当てされることです。これは私が望んでいるものではありません。

前述のスレッドで提供されている 2 番目の提案は、contentArrayバインディングを使用し、@array演算子をモデル キー パスに適用することです。私はそれを試しましたNSArrayController.

contentSet私が見つけた別のオプションは、バインディングでソート記述子を使用することです。contentSetこれには、バインディングを機能させるためにリレーションを順序なしにし、特に順序を管理するために使用される新しい属性を導入する必要があります。これにはさらに、カスタムの順序付けメカニズムを実装する必要があり、モデルが台無しになります。正直なところ、この解決策は避けたいと思います。

私の質問は非常に明確です: を使用して順序付けられた Core Data 関係を管理する方法はありますNSArrayControllerか? もしそうなら、できるだけ痛みを少なくする最善の方法はどれですか?

4

1 に答える 1

11

NSArrayController が順序付けられた関係をサポートしていないことは、非常に残念です。バインディング技術の熱心な観察者として、Apple が何も言わずにバインディング技術を「放棄」したように見えるのは最適とは言えないと思います。バインディングに関して Apple が導入した最後の注目すべき変更は、NSTreeController のバグ修正です。それは 10.6/10.7 の場合だと思います。Apple はバインディング技術にこれ以上触れたくないようです。バインディングが本当に素晴らしい場合があるため、その理由はわかりません。それらは「90%の解決策」になる可能性があります。プロトタイピング中はこれで問題ありません。私は意味のあるバインディングを使用しており、順序付けられた関係をサポートする NSArrayController を持つことは素晴らしいことです。

すでに言及されている解決策のほとんどは、実際の解決策ではありません。しかし、これは依存します。ここで考えるべきことがあります:

  1. iCloud のサポートを計画している場合は、iCloud の Core Data がそれらをサポートしていないため、とにかく順序付けられた関係を使用しない/使用できません。
  2. 順序付けられた関係はかなり新しいものであり、オブジェクトの順序付けられたコレクションに対する欲求はそれよりずっと前から存在していたため、Core Data には順序付けられた関係を模倣する方法が必要です。順序付けられた関係が利用可能になる前にコア データを食べる世界の 99.9% が何をしたかを既に指摘しました: 追加の属性で並べ替えます。あなたはこれがモデルを台無しにしていると指摘しましたが、私は同意しません: 真のモデル データを必ずしも「表す」とは限らない追加の属性をモデルに追加する必要があることは事実です。しかし、モデル内に何個の順序付けられた関係を計画しているでしょうか? 通常、アプリケーションごとにそれほど多くはありません。少し汚い感じがしますが、これは Core Data の少なくとも 3 つのメジャー リリース (10.4、10.5、および 10.6) で多くの人が行ってきたことです。今日でも、このソリューションは下位互換性のために、または iCloud を使用したい場合に使用されています。それは「実用的な」ソリューションです。いいものではありませんが、実用的です。また、注意してください: 順序付き関係を使用していたとしても、オブジェクトの順序をどこかに保存する必要があります。SQLite ストアを使用している場合、順序付けられた関係を持つと、NSSQLiteStore が追加の列を作成します。列の名前は Z_FOK_$RELATIONSHIPNAME です。したがって、順序付けられた関係を使用することによって、とにかくフードの下で行われる何かを行うだけです。これは、順序付けられた関係または追加の属性を使用している場合、純粋な技術的観点からは実際には問題にならないことを意味します。根本的な技術的問題は変わりません。秩序だった関係は魔法ではありません。それは「実用的な」ソリューションです。いいものではありませんが、実用的です。また、注意してください: 順序付き関係を使用していたとしても、オブジェクトの順序をどこかに保存する必要があります。SQLite ストアを使用している場合、順序付けられた関係を持つと、NSSQLiteStore が追加の列を作成します。列の名前は Z_FOK_$RELATIONSHIPNAME です。したがって、順序付けられた関係を使用することによって、とにかくフードの下で行われる何かを行うだけです。これは、順序付けられた関係または追加の属性を使用している場合、純粋な技術的観点からは実際には問題にならないことを意味します。根本的な技術的問題は変わりません。秩序だった関係は魔法ではありません。それは「実用的な」ソリューションです。いいものではありませんが、実用的です。また、注意してください: 順序付き関係を使用していたとしても、オブジェクトの順序をどこかに保存する必要があります。SQLite ストアを使用している場合、順序付けられた関係を持つと、NSSQLiteStore が追加の列を作成します。列の名前は Z_FOK_$RELATIONSHIPNAME です。したがって、順序付けられた関係を使用することによって、とにかくフードの下で行われる何かを行うだけです。これは、順序付けられた関係または追加の属性を使用している場合、純粋な技術的観点からは実際には問題にならないことを意味します。根本的な技術的問題は変わりません。秩序だった関係は魔法ではありません。順序付き関係を使用していたとしても、オブジェクトの順序はどこかに保存する必要があります。SQLite ストアを使用している場合、順序付けられた関係を持つと、NSSQLiteStore が追加の列を作成します。列の名前は Z_FOK_$RELATIONSHIPNAME です。したがって、順序付けられた関係を使用することによって、とにかくフードの下で行われる何かを行うだけです。これは、順序付けられた関係または追加の属性を使用している場合、純粋な技術的観点からは実際には問題にならないことを意味します。根本的な技術的問題は変わりません。秩序だった関係は魔法ではありません。順序付き関係を使用していたとしても、オブジェクトの順序はどこかに保存する必要があります。SQLite ストアを使用している場合、順序付けられた関係を持つと、NSSQLiteStore が追加の列を作成します。列の名前は Z_FOK_$RELATIONSHIPNAME です。したがって、順序付けられた関係を使用することによって、とにかくフードの下で行われる何かを行うだけです。これは、順序付けられた関係または追加の属性を使用している場合、純粋な技術的観点からは実際には問題にならないことを意味します。根本的な技術的問題は変わりません。秩序だった関係は魔法ではありません。したがって、順序付けられた関係を使用することによって、とにかくフードの下で行われる何かを行うだけです。これは、順序付けられた関係または追加の属性を使用している場合、純粋な技術的観点からは実際には問題にならないことを意味します。根本的な技術的問題は変わりません。秩序だった関係は魔法ではありません。したがって、順序付けられた関係を使用することによって、とにかくフードの下で行われる何かを行うだけです。これは、順序付けられた関係または追加の属性を使用している場合、純粋な技術的観点からは実際には問題にならないことを意味します。根本的な技術的問題は変わりません。秩序だった関係は魔法ではありません。
  3. 「追加属性」ソリューションを計画している場合は、この属性の値を何度も調整する必要があることに注意してください。ユーザーがドラッグ アンド ドロップで順序を変更するたびに、属性の値を変更する必要があります。これは無駄に思えますが、実際にはそうではありません。さらに悪いケース: 行 0 のオブジェクトを最後の可能な行のオブジェクトと交換しているユーザーは、2 つの属性変更のみを引き起こします。テーブルビューでドラッグアンドドロップによって行うことができる変更を表すために必要な変更の単純なソリューションの複雑さは、O(n) です。ここで、n は選択された行の数です。通常、ユーザーは一度に 10000000 行を並べ替えることはなく、実装がそれほど難しくないよりスマートなアルゴリズムが世の中にあるため、これは実際にはそれほど悪くはありません。
  4. 最もクリーンなソリューションを探している場合は、NSArrayController をサブクラス化し、「orderedContentSet」バインディングを自分で追加する必要があります。その方法については、Cocoa Bindings Programming トピック ガイドを参照してください。ガイドには例が含まれています: https://developer.apple.com/library/mac/documentation/cocoa/conceptual/CocoaBindings/Concepts/HowDoBindingsWork.html (リスト 2)。これの悪い点は、通常は使用できない NSArrayController をサブクラス化していることです。多くの人は、サブクラス化を正当化できない理由で NSArrayController をサブクラス化する傾向があります。ただし、この場合、最もクリーンなソリューションを使用する場合は、NSArrayController をサブクラス化することが正当化されます。
  5. 3.については、多くのことを行う一般的なソリューションがあります。それらを使用しないでください。
于 2013-12-22T12:54:31.827 に答える