NSMutableArray
KVO によって監視されるプロパティを持つビュー コントローラーがあります。
@interface MyViewController ()
@property (strong, nonatomic) NSMutableArray *values;
@end
@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.values = [NSMutableArray array];
[self addObserver:self forKeyPath:@"self.values" options:0 context:nil];
}
- (void)dealloc
{
[self removeObserver:self forKeyPath:@"self.values"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"self.values"])
{
// The code here is a bit more complex than that, but the main idea
// is to mutate the object
[self.values addObject:[NSDate date]]; // This line triggers a KVO notification, causing an infinite recursion
}
}
@end
私の実装の目標は、配列内の各製品に割引を適用し、製品が配列に追加されるたびにこれらの割引を再計算することです。
通知を受け取ったときに監視対象のプロパティを変更したいのですが、明らかに上記のコードは機能せず、無限再帰に入ります。
1 つの解決策は、最初のオブザーバーを削除observeValueForKeyPath...
し、最後にオブザーバーを再度追加することです。
ただし、これは少し醜いように見えます。また、プロパティがobserveValueForKeyPath...
別のスレッドで実行されているときに、あるスレッドでプロパティが変更されるという問題が発生する可能性があります。
編集:ウェインが指摘したように、ここでの本当の問題は、 myNSMutableArray
self.value
に不変オブジェクト( NSDictionnary
s)が含まれる可能性があり、それらを可変の同等のものに置き換える方法がないことです:
[self.value replaceObjectAtIndex:0 withObject:[self.value[0] mutableCopy]];
KVO通知をトリガーせずに。