CPDictionary is now KVO compliant.

This commit is contained in:
Ross Boucher committed 2010-05-24 10:09:39 -07:00
1 parent 7519b7ab63
commit be26ab9201
3 files changed
+87 -3

No files matched your search

+2 -2
View File
@@ -316,7 +316,7 @@
*/
- (CPArray)allKeys
{
return _keys;
return [_keys copy];
}
/*!
@@ -475,7 +475,7 @@
var index = keysForRemoval.length;
while (index--)
self.removeValueForKey(keysForRemoval[index]);
[self removeObjectForKey:keysForRemoval[index]];
}
/*
+63 -1
View File
@@ -226,7 +226,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew|CPKeyValueObservingOptionOld,
var currentClass = _nativeClass,
kvoClassName = "$KVO_"+class_getName(_nativeClass),
existingKVOClass = objj_lookUpClass(kvoClassName);
if (existingKVOClass)
{
_targetObject.isa = existingKVOClass;
@@ -247,6 +247,18 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew|CPKeyValueObservingOptionOld,
class_addMethod(kvoClass, method_getName(method), method_getImplementation(method), "");
}
if ([_targetObject isKindOfClass:[CPDictionary class]])
{
var methodList = _CPKVOModelDictionarySubclass.method_list,
count = methodList.length;
for (var i=0; i<count; i++)
{
var method = methodList[i];
class_addMethod(kvoClass, method_getName(method), method_getImplementation(method), "");
}
}
_targetObject.isa = kvoClass;
}
@@ -565,6 +577,56 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew|CPKeyValueObservingOptionOld,
@end
@implementation _CPKVOModelDictionarySubclass
{
}
- (void)removeAllObjects
{
var keys = [self allKeys],
count = [keys count];
for (var i = 0; i < count; i++)
[self willChangeValueForKey:keys[i]];
var superClass = [self class],
methodSelector = @selector(removeAllObjects),
methodImp = class_getMethodImplementation(superClass, methodSelector);
methodImp(self, methodSelector);
for (var i = 0; i < count; i++)
[self didChangeValueForKey:keys[i]];
}
- (void)removeObjectForKey:(id)aKey
{
[self willChangeValueForKey:aKey];
var superClass = [self class],
methodSelector = @selector(removeObjectForKey:),
methodImp = class_getMethodImplementation(superClass, methodSelector);
methodImp(self, methodSelector, aKey);
[self didChangeValueForKey:aKey];
}
- (void)setObject:(id)anObject forKey:(id)aKey
{
[self willChangeValueForKey:aKey];
var superClass = [self class],
methodSelector = @selector(setObject:forKey:),
methodImp = class_getMethodImplementation(superClass, methodSelector);
methodImp(self, methodSelector, anObject, aKey);
[self didChangeValueForKey:aKey];
}
@end
@implementation _CPKVOForwardingObserver : CPObject
{
id _object;
+22
View File
@@ -122,6 +122,22 @@
}
- (void)testDictionary
{
var dict = [[CPDictionary alloc] init];
[dict setObject:@"Bob Jones" forKey:@"dictionaryKey"];
[dict addObserver:self
forKeyPath:@"dictionaryKey"
options:nil
context:"testDictionary"];
[dict setObject:@"Jo Bob Ray" forKey:@"dictionaryKey"];
[self assertTrue: _sawObservation message:"Never recieved an observation"];
}
- (void)testPriorObservationOption
{
_sawPriorObservation = NO;
@@ -611,6 +627,12 @@
[self assert:anObject equals:bob];
break;
case "testDictionary":
[self assert:aKeyPath equals:"dictionaryKey"];
[self assert:oldValue equals:"Bob Jones"];
[self assert:newValue equals:"Jo Bob Ray"];
break;
default:
[self assertFalse:YES message:"unhandled observation, must be an error"];
return;