Fixed NSKeyValueMutableArray/Set to post KVO notifications only if

+automaticallyNotifiesObserversForKey: returns YES, and match Cocoa behavior.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@37622 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Quentin Mathe 2014-01-20 17:18:57 +00:00
parent 28aac8871f
commit 22b874ba15
3 changed files with 260 additions and 141 deletions

View file

@ -1,3 +1,10 @@
2014-01-20 Quentin Mathe <quentin.mathe@gmail.com>
* Source/NSKeyValueMutableArray.m:
* Source/NSKeyValueMutableSet.m:
Don't post KVO notifications if +automaticallyNotifiesObserversForKey:
returns NO, this ensures we match Cocoa behavior.
2014-01-18 Quentin Mathe <quentin.mathe@gmail.com>
* Source/NSObject.m (-respondsToSelector,

View file

@ -35,6 +35,7 @@
NSString *key;
NSMutableArray *array;
BOOL otherChangeInProgress;
BOOL notifiesObservers;
}
+ (NSKeyValueMutableArray *) arrayForKey: (NSString *)aKey ofObject: (id)anObject;
@ -126,6 +127,8 @@
object = anObject;
key = [aKey copy];
otherChangeInProgress = NO;
notifiesObservers =
[[anObject class] automaticallyNotifiesObserversForKey: aKey];
}
return self;
}
@ -224,7 +227,7 @@
{
NSIndexSet *indexes = nil;
if (!otherChangeInProgress)
if (notifiesObservers && !otherChangeInProgress)
{
indexes = [NSIndexSet indexSetWithIndex: index];
[object willChange: NSKeyValueChangeRemoval
@ -233,7 +236,7 @@
}
[removeObjectInvocation setArgument: &index atIndex: 2];
[removeObjectInvocation invoke];
if (!otherChangeInProgress)
if (notifiesObservers && !otherChangeInProgress)
{
[object didChange: NSKeyValueChangeRemoval
valuesAtIndexes: indexes
@ -245,7 +248,7 @@
{
NSIndexSet *indexes = nil;
if (!otherChangeInProgress)
if (notifiesObservers && !otherChangeInProgress)
{
indexes = [NSIndexSet indexSetWithIndex: index];
[object willChange: NSKeyValueChangeInsertion
@ -255,7 +258,7 @@
[insertObjectInvocation setArgument: &anObject atIndex: 2];
[insertObjectInvocation setArgument: &index atIndex: 3];
[insertObjectInvocation invoke];
if (!otherChangeInProgress)
if (notifiesObservers && !otherChangeInProgress)
{
[object didChange: NSKeyValueChangeInsertion
valuesAtIndexes: indexes
@ -266,9 +269,8 @@
- (void) replaceObjectAtIndex: (NSUInteger)index withObject: (id)anObject
{
NSIndexSet *indexes = nil;
BOOL triggerNotifications = !otherChangeInProgress;
if (triggerNotifications)
if (notifiesObservers && !otherChangeInProgress)
{
otherChangeInProgress = YES;
indexes = [NSIndexSet indexSetWithIndex: index];
@ -287,7 +289,7 @@
[self removeObjectAtIndex: index];
[self insertObject: anObject atIndex: index];
}
if (triggerNotifications)
if (notifiesObservers && !otherChangeInProgress)
{
[object didChange: NSKeyValueChangeReplacement
valuesAtIndexes: indexes
@ -336,7 +338,7 @@
NSIndexSet *indexes = nil;
NSMutableArray *temp;
if (!otherChangeInProgress)
if (notifiesObservers && !otherChangeInProgress)
{
indexes = [NSIndexSet indexSetWithIndex: index];
[object willChange: NSKeyValueChangeRemoval
@ -350,7 +352,7 @@
[setArrayInvocation setArgument: &temp atIndex: 2];
[setArrayInvocation invoke];
if (!otherChangeInProgress)
if (notifiesObservers && !otherChangeInProgress)
{
[object didChange: NSKeyValueChangeRemoval
valuesAtIndexes: indexes
@ -363,7 +365,7 @@
NSIndexSet *indexes = nil;
NSMutableArray *temp;
if (!otherChangeInProgress)
if (notifiesObservers && !otherChangeInProgress)
{
indexes = [NSIndexSet indexSetWithIndex: index];
[object willChange: NSKeyValueChangeInsertion
@ -377,7 +379,7 @@
[setArrayInvocation setArgument: &temp atIndex: 2];
[setArrayInvocation invoke];
if (!otherChangeInProgress)
if (notifiesObservers && !otherChangeInProgress)
{
[object didChange: NSKeyValueChangeInsertion
valuesAtIndexes: indexes
@ -390,7 +392,7 @@
NSIndexSet *indexes = nil;
NSMutableArray *temp;
if (!otherChangeInProgress)
if (notifiesObservers && !otherChangeInProgress)
{
indexes = [NSIndexSet indexSetWithIndex: index];
[object willChange: NSKeyValueChangeReplacement
@ -405,7 +407,7 @@
[setArrayInvocation setArgument: &temp atIndex: 2];
[setArrayInvocation invoke];
if (!otherChangeInProgress)
if (notifiesObservers && !otherChangeInProgress)
{
[object didChange: NSKeyValueChangeReplacement
valuesAtIndexes: indexes
@ -458,67 +460,102 @@
- (void) addObject: (id)anObject
{
NSIndexSet *indexes = [NSIndexSet indexSetWithIndex: [array count]];
NSIndexSet *indexes = nil;
[object willChange: NSKeyValueChangeInsertion
valuesAtIndexes: indexes
forKey: key];
if (notifiesObservers)
{
indexes = [NSIndexSet indexSetWithIndex: [array count]];
[object willChange: NSKeyValueChangeInsertion
valuesAtIndexes: indexes
forKey: key];
}
[array addObject: anObject];
[object didChange: NSKeyValueChangeInsertion
valuesAtIndexes: indexes
forKey: key];
if (notifiesObservers)
{
[object didChange: NSKeyValueChangeInsertion
valuesAtIndexes: indexes
forKey: key];
}
}
- (void) removeObjectAtIndex: (NSUInteger)index
{
NSIndexSet *indexes = [NSIndexSet indexSetWithIndex: index];
NSIndexSet *indexes = nil;
[object willChange: NSKeyValueChangeRemoval
valuesAtIndexes: indexes
forKey: key];
if (notifiesObservers)
{
indexes = [NSIndexSet indexSetWithIndex: index];
[object willChange: NSKeyValueChangeRemoval
valuesAtIndexes: indexes
forKey: key];
}
[array removeObjectAtIndex: index];
[object didChange: NSKeyValueChangeRemoval
valuesAtIndexes: indexes
forKey: key];
if (notifiesObservers)
{
[object didChange: NSKeyValueChangeRemoval
valuesAtIndexes: indexes
forKey: key];
}
}
- (void) insertObject: (id)anObject atIndex: (NSUInteger)index
{
NSIndexSet *indexes = [NSIndexSet indexSetWithIndex: index];
NSIndexSet *indexes = nil;
[object willChange: NSKeyValueChangeInsertion
valuesAtIndexes: indexes
forKey: key];
if (notifiesObservers)
{
indexes = [NSIndexSet indexSetWithIndex: index];
[object willChange: NSKeyValueChangeInsertion
valuesAtIndexes: indexes
forKey: key];
}
[array insertObject: anObject atIndex: index];
[object didChange: NSKeyValueChangeInsertion
valuesAtIndexes: indexes
forKey: key];
if (notifiesObservers)
{
[object didChange: NSKeyValueChangeInsertion
valuesAtIndexes: indexes
forKey: key];
}
}
- (void) removeLastObject
{
NSIndexSet *indexes = [NSIndexSet indexSetWithIndex: [array count] - 1];
NSIndexSet *indexes = nil;
[object willChange: NSKeyValueChangeRemoval
valuesAtIndexes: indexes
forKey: key];
if (notifiesObservers)
{
indexes = [NSIndexSet indexSetWithIndex: [array count] - 1];
[object willChange: NSKeyValueChangeRemoval
valuesAtIndexes: indexes
forKey: key];
}
[array removeObjectAtIndex: [indexes firstIndex]];
[object didChange: NSKeyValueChangeRemoval
valuesAtIndexes: indexes
forKey: key];
if (notifiesObservers)
{
[object didChange: NSKeyValueChangeRemoval
valuesAtIndexes: indexes
forKey: key];
}
}
- (void) replaceObjectAtIndex: (NSUInteger)index withObject: (id)anObject
{
NSIndexSet *indexes = [NSIndexSet indexSetWithIndex: index];
NSIndexSet *indexes = nil;
[object willChange: NSKeyValueChangeReplacement
valuesAtIndexes: indexes
forKey: key];
if (notifiesObservers)
{
indexes = [NSIndexSet indexSetWithIndex: index];
[object willChange: NSKeyValueChangeReplacement
valuesAtIndexes: indexes
forKey: key];
}
[array replaceObjectAtIndex: index withObject: anObject];
[object didChange: NSKeyValueChangeReplacement
valuesAtIndexes: indexes
forKey: key];
if (notifiesObservers)
{
[object didChange: NSKeyValueChangeReplacement
valuesAtIndexes: indexes
forKey: key];
}
}

View file

@ -33,6 +33,7 @@
NSString *key;
NSMutableSet *set;
BOOL changeInProgress;
BOOL notifiesObservers;
}
+ (NSKeyValueMutableSet*) setForKey: (NSString*)aKey ofObject: (id)anObject;
@ -128,6 +129,8 @@
object = anObject;
key = [aKey copy];
changeInProgress = NO;
notifiesObservers =
[[anObject class] automaticallyNotifiesObserversForKey: aKey];
}
return self;
}
@ -281,7 +284,7 @@
{
if (addObjectInvocation)
{
if (!changeInProgress)
if (notifiesObservers && !changeInProgress)
{
[object willChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
@ -289,7 +292,7 @@
}
[addObjectInvocation setArgument: &anObject atIndex: 2];
[addObjectInvocation invoke];
if (!changeInProgress)
if (notifiesObservers && !changeInProgress)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
@ -304,28 +307,36 @@
- (void) unionSet: (NSSet *)aSet
{
changeInProgress = YES;
[object willChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
usingObjects: aSet];
if (notifiesObservers)
{
changeInProgress = YES;
[object willChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
usingObjects: aSet];
}
if (addSetInvocation)
{
[addSetInvocation setArgument: &aSet atIndex: 2];
[addSetInvocation invoke];
}
else
[super unionSet: aSet];
[object didChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
usingObjects: aSet];
changeInProgress = NO;
{
[super unionSet: aSet];
}
if (notifiesObservers)
{
changeInProgress = NO;
[object didChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
usingObjects: aSet];
}
}
- (void) removeObject: (id)anObject
{
if (removeObjectInvocation)
{
if (!changeInProgress)
if (notifiesObservers && !changeInProgress)
{
[object willChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
@ -333,7 +344,7 @@
}
[removeObjectInvocation setArgument: &anObject atIndex: 2];
[removeObjectInvocation invoke];
if (!changeInProgress)
if (notifiesObservers && !changeInProgress)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
@ -346,10 +357,13 @@
- (void) minusSet: (NSSet *)aSet
{
changeInProgress = YES;
[object willChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: aSet];
if (notifiesObservers)
{
changeInProgress = YES;
[object willChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: aSet];
}
if (removeSetInvocation)
{
[removeSetInvocation setArgument: &aSet atIndex: 2];
@ -359,18 +373,24 @@
{
[super minusSet: aSet];
}
[object didChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: aSet];
changeInProgress = NO;
if (notifiesObservers)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: aSet];
changeInProgress = NO;
}
}
- (void) intersectSet: (NSSet *)aSet
{
changeInProgress = YES;
[object willChangeValueForKey: key
withSetMutation: NSKeyValueIntersectSetMutation
usingObjects: aSet];
if (notifiesObservers)
{
changeInProgress = YES;
[object willChangeValueForKey: key
withSetMutation: NSKeyValueIntersectSetMutation
usingObjects: aSet];
}
if (intersectInvocation)
{
[intersectInvocation setArgument: &aSet atIndex: 2];
@ -380,18 +400,24 @@
{
[super intersectSet: aSet];
}
[object didChangeValueForKey: key
withSetMutation: NSKeyValueIntersectSetMutation
usingObjects: aSet];
changeInProgress = NO;
if (notifiesObservers)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueIntersectSetMutation
usingObjects: aSet];
changeInProgress = NO;
}
}
- (void) setSet: (NSSet *)aSet
{
changeInProgress = YES;
[object willChangeValueForKey: key
withSetMutation: NSKeyValueSetSetMutation
usingObjects: aSet];
if (notifiesObservers)
{
changeInProgress = YES;
[object willChangeValueForKey: key
withSetMutation: NSKeyValueSetSetMutation
usingObjects: aSet];
}
if (setSetInvocation)
{
[setSetInvocation setArgument: &aSet atIndex: 2];
@ -401,10 +427,13 @@
{
[super setSet: aSet];
}
[object didChangeValueForKey: key
withSetMutation: NSKeyValueSetSetMutation
usingObjects: aSet];
changeInProgress = NO;
if (notifiesObservers)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueSetSetMutation
usingObjects: aSet];
changeInProgress = NO;
}
}
@end
@ -443,108 +472,154 @@
- (void) setSet: (id)aSet
{
[object willChangeValueForKey: key
withSetMutation: NSKeyValueSetSetMutation
usingObjects: aSet];
if (notifiesObservers)
{
[object willChangeValueForKey: key
withSetMutation: NSKeyValueSetSetMutation
usingObjects: aSet];
}
[setSetInvocation setArgument: &aSet atIndex: 2];
[setSetInvocation invoke];
[object didChangeValueForKey: key
withSetMutation: NSKeyValueSetSetMutation
usingObjects: aSet];
if (notifiesObservers)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueSetSetMutation
usingObjects: aSet];
}
}
- (void) removeAllObjects
{
NSSet *nothing;
NSSet *theSet = [NSSet setWithSet: [object valueForKey: key]];
[object willChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: theSet];
if (notifiesObservers)
{
[object willChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: theSet];
}
nothing = [NSSet set];
[setSetInvocation setArgument: &nothing atIndex: 2];
[setSetInvocation invoke];
[object didChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: theSet];
if (notifiesObservers)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: theSet];
}
}
- (void) addObject: (id)anObject
{
NSMutableSet *temp;
NSSet *unionSet;
NSSet *unionSet = [NSSet setWithObject: anObject];
unionSet = [NSSet setWithObject: anObject];
[object willChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
usingObjects: unionSet];
if (notifiesObservers)
{
[object willChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
usingObjects: unionSet];
}
temp = [NSMutableSet setWithSet: [object valueForKey: key]];
[temp addObject: anObject];
[setSetInvocation setArgument: &temp atIndex: 2];
[setSetInvocation invoke];
[object didChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
usingObjects: unionSet];
if (notifiesObservers)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
usingObjects: unionSet];
}
}
- (void) removeObject: (id)anObject
{
NSMutableSet *temp;
NSSet *minusSet = [NSSet setWithObject: anObject];
[object willChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: minusSet];
if (notifiesObservers)
{
[object willChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: minusSet];
}
temp = [NSMutableSet setWithSet: [object valueForKey: key]];
[temp removeObject: anObject];
[setSetInvocation setArgument: &temp atIndex: 2];
[setSetInvocation invoke];
[object didChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: minusSet];
if (notifiesObservers)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: minusSet];
}
}
- (void) unionSet: (id)anObject
{
NSMutableSet *temp;
[object willChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
usingObjects: anObject];
if (notifiesObservers)
{
[object willChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
usingObjects: anObject];
}
temp = [NSMutableSet setWithSet: [object valueForKey: key]];
[temp unionSet: anObject];
[setSetInvocation setArgument: &temp atIndex: 2];
[setSetInvocation invoke];
[object didChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
usingObjects: anObject];
if (notifiesObservers)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
usingObjects: anObject];
}
}
- (void) minusSet: (id)anObject
{
NSMutableSet *temp;
[object willChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: anObject];
if (notifiesObservers)
{
[object willChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: anObject];
}
temp = [NSMutableSet setWithSet: [object valueForKey: key]];
[temp minusSet: anObject];
[setSetInvocation setArgument: &temp atIndex: 2];
[setSetInvocation invoke];
[object didChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: anObject];
if (notifiesObservers)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: anObject];
}
}
- (void) intersectSet: (id)anObject
{
NSMutableSet *temp;
[object willChangeValueForKey: key
withSetMutation: NSKeyValueIntersectSetMutation
usingObjects: anObject];
if (notifiesObservers)
{
[object willChangeValueForKey: key
withSetMutation: NSKeyValueIntersectSetMutation
usingObjects: anObject];
}
temp = [NSMutableSet setWithSet: [object valueForKey: key]];
[temp intersectSet: anObject];
[setSetInvocation setArgument: &temp atIndex: 2];
[setSetInvocation invoke];
[object didChangeValueForKey: key
withSetMutation: NSKeyValueIntersectSetMutation
usingObjects: anObject];
if (notifiesObservers)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueIntersectSetMutation
usingObjects: anObject];
}
}
@end
@ -605,14 +680,14 @@
- (void) addObject: (id)anObject
{
if (!changeInProgress)
if (notifiesObservers && !changeInProgress)
{
[object willChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
usingObjects: [NSSet setWithObject: anObject]];
}
[set addObject: anObject];
if (!changeInProgress)
if (notifiesObservers && !changeInProgress)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
@ -622,14 +697,14 @@
- (void) removeObject: (id)anObject
{
if (!changeInProgress)
if (notifiesObservers && !changeInProgress)
{
[object willChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: [NSSet setWithObject:anObject]];
}
[set removeObject: anObject];
if (!changeInProgress)
if (notifiesObservers && !changeInProgress)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
@ -639,14 +714,14 @@
- (void) unionSet: (id)anObject
{
if (!changeInProgress)
if (notifiesObservers && !changeInProgress)
{
[object willChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
usingObjects: [NSSet setWithObject: anObject]];
}
[set unionSet: anObject];
if (!changeInProgress)
if (notifiesObservers && !changeInProgress)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueUnionSetMutation
@ -656,14 +731,14 @@
- (void) minusSet: (id)anObject
{
if (!changeInProgress)
if (notifiesObservers && !changeInProgress)
{
[object willChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
usingObjects: [NSSet setWithObject: anObject]];
}
[set minusSet: anObject];
if (!changeInProgress)
if (notifiesObservers && !changeInProgress)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueMinusSetMutation
@ -673,14 +748,14 @@
- (void) intersectSet: (id)anObject
{
if (!changeInProgress)
if (notifiesObservers && !changeInProgress)
{
[object willChangeValueForKey: key
withSetMutation: NSKeyValueIntersectSetMutation
usingObjects: [NSSet setWithObject: anObject]];
}
[set intersectSet: anObject];
if (!changeInProgress)
if (notifiesObservers && !changeInProgress)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueIntersectSetMutation
@ -690,14 +765,14 @@
- (void) setSet: (id)anObject
{
if (!changeInProgress)
if (notifiesObservers && !changeInProgress)
{
[object willChangeValueForKey: key
withSetMutation: NSKeyValueSetSetMutation
usingObjects: [NSSet setWithObject: anObject]];
}
[set setSet: anObject];
if (!changeInProgress)
if (notifiesObservers && !changeInProgress)
{
[object didChangeValueForKey: key
withSetMutation: NSKeyValueSetSetMutation