Grand Central Dispatchのディスパッチソースを使用して、プロパティ変更の観測を合体させ、処理できるよりも頻繁に発生しないようにすることができます。
@implementation Controller
{
dispatch_source_t source;
}
- (id)init
{
self = [super init];
if (self)
{
//We are using data add source type, but not actually using the added data.
source = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_main_queue());
dispatch_source_set_event_handler(source, ^{
//Insert your network call to load data from the network.
//The event handler will only be called when another event handler is not being processed. So you won't attempt to do another network call until the last call was completed.
});
//Dispatch sources always start out suspended so you can add the event handler. You must resume them after creating them if you want events to be delivered)
dispatch_resume(source);
}
return self;
}
- (void)dealloc
{
dispatch_release(source);
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
//Tell dispatch source some data changed. It will only call the event handler if an event is not currently being handled.
//You could add a custom timer based coalesce here for when no events are currently being processed if you want to delay all initial events to potentially wait for more changes
dispatch_source_merge_data(source, 1);
}
@end
したがって、最初のプロパティ変更通知は、ディスパッチソースイベントハンドラーをトリガーします。既存のイベントの実行中に発生する後続のプロパティ変更は、最後のイベントが完了するとすぐに実行されるようにキューに入れられます。つまり、5つのプロパティがすばやく連続して変更されると、(5つのネットワーク呼び出しではなく)2つのネットワーク呼び出しが発生します。2番目のネットワーク呼び出しを排除するために通知への即時の応答性を犠牲にしたい場合は、イベントが処理されていないときにカスタムタイマーベースの合体を追加できます。