7

Key-ValueコーディングプログラミングガイドKey-Value監視プログラミングガイドモデルオブジェクト実装ガイドを読み、トピックに関する多くのStackOverflowエントリを読み、さまざまなモデリングシナリオを試した後、私はよく理解しているように感じます。データをモデル化する方法。

プライベートivarに裏打ちされた、すべての属性とto-one関係に宣言されたプロパティを使用することになります。プライベートに書き込み可能である必要がある読み取り専用属性の場合readonly、インターフェイス宣言で属性を使用してから、ファイルで宣言されたクラス拡張.hの属性でプロパティを再宣言します。クラスメソッド内では、常にドット構文でプロパティアクセサーを使用し、プライベートivarに直接アクセスすることはありません。readwrite.m

ただし、まだ戸惑うことが1つあります。特に、コレクションがパブリックに不変であるがプライベートに変更可能である場合(つまり、モデルオブジェクトのコンシューマーはコレクションにオブジェクトを追加または削除できませんが、コレクションのコンテンツは、クラスによって非公開で管理されます)。

私は、to-many関係(、、など)にKVCアクセサーメソッドを実装する方法を理解してcountOf<Key>objectsIn<Key>AtIndexます。これは、これまで私がたどってきたルートです。

ただし、宣言されたプロパティを使用して関係を公開し、KVCアクセサーメソッドを実装しないサンプルコードをいくつか見てきましたが、それでもKey-Valueを監視できます。例えば:

@interface MyModel : NSObject
{
  // Note that the ivar is a mutable array,
  // while the property is declared as an immutable array.
  @private NSMutableArray *transactions_;
}

@property (nonatomic, retain, readonly) NSArray transactions;

@end

--------------------

@implementation MyModel

@synthesize transactions = transactions_;

- (void)privateMethodThatManagesTransactions
{
  [[self mutableArrayValueForKey:@"transactions"] addObject:t];
}

@end

コンシューマオブジェクトがキーパスのMyModelインスタンスのオブザーバーとして自分自身を追加した場合、"transactions"トランザクションがコレクションに追加またはコレクションから削除されるたびに通知されtransactionsます(変更がメソッドを介して行われているmutableArrayValueForKey:場合)。

私には、コレクションKVCアクセサーを手動でコーディングする必要がなく、コードをクリーンに保つため、これは多くの関係を公開するための最もクリーンな方法のように思えます。

しかし、それはAppleのドキュメントで宣伝されている方法ではないようで、それが機能するという事実が信頼できない副作用にすぎないのではないかと思わずにはいられません。

ですから、私が取り組み始めているプロジェクトの実際のモデルクラスでいずれかの手法に取り組む前に、経験豊富なCocoa開発者の意見やアドバイスをもらいたいと思います。

したがって、問題は、プロパティを使用してto-many関係をモデル化する場合でも、KVCアクセサー/ミューテーターメソッドを実装する必要があるかどうかです。

アップデート

上記の例のように、to-manyプロパティをとして宣言した場合でもreadonly、外部コードmutableArrayValueForKey:@"transactions"はモデルオブジェクトを呼び出して、コレクションを変更できます。これは、宣言されたプロパティをto-many関係に使用することは道のりではないことを示しているようですが、それでも私はそれを完全に理解していないように感じます...

4

1 に答える 1

6

はい。

ただし、まだ戸惑う側面が1つあります。それは、特にコレクションが公的には不変であるが、私的には不変である場合に、多対多の関係を適切にモデル化する方法です。

簡単:readonlyヘッダーのようにプロパティを宣言してから、実装ファイルのクラス拡張のように再宣言します。readwrite, copy

私は、to-many関係(、、など)にKVCアクセサーメソッドを実装する方法を理解してcountOf<Key>objectsIn<Key>AtIndexます。これは、これまで私がたどってきたルートです。

変異型のものもあります。これらを使用すると、を使用する必要はありませんmutableArrayValueForKey:。代わりに、変異型アクセサーを直接使用できます。KVOは、プロパティのオブザーバーとして初めて何かが追加されたときにこれらのメソッドをラップするため、引き続きKVO通知を受け取ります。

ブログに、ミューテイターアクセサーを含むアクセサーセレクターフォーマットのリストがあります。

編集:

上記の例のように、to-manyプロパティを読み取り専用として宣言した場合でも、外部コードmutableArrayValueForKey:@"transactions"はモデルオブジェクトを呼び出して、コレクションを変更できます。

これは、変異型アクセサーを使用して回避することを習慣にする良い理由mutableArrayValueForKey:です。コンパイラの警告(そのような[public]メソッドがない)を試したときに、クラスの外部からミューテーションメッセージを送信することはありません。

利用可能であり、誰かがそれを使用するリスクがあるにもかかわらずmutableArrayValueForKey:、KVO準拠のプロパティここに行く方法です。

于 2009-06-03T19:16:09.573 に答える