19

私のモデルには、イベントと呼ばれるオブジェクトの配列があります。新しいオブジェクトがイベントに追加されるたびに、コントローラーに通知したいと思います。

これを行う良い方法は、KVOパターンを使用して、イベントが変更されたときに通知を受けることだと思いました(新しいオブジェクトが追加されたことから)

// AppDelegate
// events is a NSMutableArray @property/@synthesize etc...

[appDelagate addObserver:self
               forKeyPath:@"events"
                  options:NSKeyValueObservingOptionNew
                  context:NULL];

しかし、observeValueForKeyPathメソッドが呼び出されておらず、配列が KVO に準拠していないことがわかりました :-(

1 つのオプションは、keyPath の willChangeValueForKey を呼び出して、メソッドを手動でトリガーすることです。

// ViewController
[self willChangeValueForKey:@"events"];
[self.events addObject:event];
[self didChangeValueForKey:@"events"];

しかし、 observeValueForKeyPathメソッドからアクセスできるように、おそらくイベント配列の前後の状態も追跡する必要があるため、これは重く感じます。

1 つのアプローチとして、(変更可能ではなく) 標準配列を使用し、新しいオブジェクトを追加するたびにイベントの新しいインスタンスを作成/設定するか、オブジェクト内の項目数を追跡する別のプロパティを作成することができます。可変配列( @"events.count" を観察できればいいのに)。

別のオプションは、NSNotificationCenter を使用することです。ブロックの使用を提案するいくつかの回答も読みました(ただし、どこから始めればよいかわかりません)。

最後に、コントローラーのインスタンスをデリゲートに保持して、関連するメッセージを送信することはできますか?

// Delegate
[myController eventsDidChange];

デリゲートからコントローラーへの参照を保持するのは奇妙ですか?

どちらを使用するのが最善のアプローチなのかを理解するのに苦労しているので、パフォーマンス、将来のコードの柔軟性、およびベスト プラクティスに関するアドバイスをいただければ幸いです。

4

2 に答える 2

18

知らないうちにコレクションが変更されるのを避けるために、変更可能なコレクションの直接的なパブリック プロパティを作成しないでください。NSArrayキー値自体は観察可能ではありませんが、1 対多のプロパティ @"events"は観察可能です。これを観察する方法は次のとおりです。

まず、不変コレクションのパブリック プロパティを宣言します。

@interface Model
@property (nonatomic, copy) NSArray *events;
@end

次に、実装で変更可能な ivar を使用してそれを戻します。

@interface Model ()
{
    NSMutableArray *_events;
}
@end

getter と setter をオーバーライドします。

@implementation Model

@synthesize events = _events;

- (NSArray *)events
{
    return [_events copy];
}

- (void)setEvents:(NSArray *)events
{
    if ([_events isEqualToArray:events] == NO)
    {
        _events = [events mutableCopy];
    }
}

@end

他のオブジェクトがモデルにイベントを追加する必要がある場合、それらは を呼び出して変更可能なプロキシ オブジェクトを取得できます-[Model mutableArrayValueForKey:@"events"]

NSMutableArray *events = [modelInstance mutableArrayValueForKey:@"events"];
[events addObject:newEvent];

これにより、毎回新しいコレクションでプロパティを設定することにより、KVO 通知がトリガーされます。パフォーマンスを向上させ、より詳細な制御を行うには、残りの配列アクセサーを実装します。

参照:挿入/削除のために NSMutableArray を観察する.

于 2012-05-03T17:39:00.250 に答える