Ich habe ein Modell, das an einen Array-Controller gebunden ist. Ich muss in der Lage sein, das Modell direkt zu aktualisieren und haben Benachrichtigungen an den Array-Controller über die Aktualisierung gesendet. Bei meiner Suche habe ich festgestellt, dass ich dies durch die Verwendung von mutableArrayValueForKey:
auf mein Modell und die Aktualisierung durch das zurückgegebene NSMutableArray.
Ich fand auch mehrere Verweise, die mich zu der Annahme verleiteten, dass ich das Modell auch aktualisieren und Benachrichtigungen senden könnte, wenn ich die KVC-konformen Getter und veränderbaren indizierten Accessoren implementieren und verwenden würde. In meinem Code implementierte ich
-countOf<Key>:
-objectIn<Key>AtIndex:
-insertObject:in<Key>AtIndex:
-removeObjectFrom<Key>AtIndex:
Aufruf von insertObject:in<Key>AtIndex:
hat nicht dazu geführt, dass meine Beobachter benachrichtigt wurden. Der folgende Code ist das kleinste Stück, das mir einfiel, um zu testen, was ich zu tun versuchte.
#import <Foundation/Foundation.h>
@interface ModelAndObserver : NSObject {
NSMutableArray *theArray;
}
@property(retain)NSMutableArray *theArray;
- (NSUInteger)countOfTheArray;
- (NSString *)objectInTheArrayAtIndex:(NSUInteger)index;
- (void)insertObject:(NSString*) string inTheArrayAtIndex:(NSUInteger)index;
- (void)removeObjectInTheArrayAtIndex:(NSUInteger)index;
@end
@implementation ModelAndObserver
@synthesize theArray;
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
NSLog(@"theArray now has %d items", [theArray count]);
}
- (NSUInteger)countOfTheArray
{
return [theArray count];
}
- (NSString *)objectInTheArrayAtIndex:(NSUInteger)index
{
return [theArray objectAtIndex:index];
}
- (void)insertObject:(NSString*) string inTheArrayAtIndex:(NSUInteger)index
{
[theArray insertObject:string atIndex:index];
}
- (void)removeObjectInTheArrayAtIndex:(NSUInteger)index
{
[theArray removeObjectAtIndex:index];
}
@end
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
ModelAndObserver *mao = [[ModelAndObserver alloc] init];
[mao addObserver:mao
forKeyPath:@"theArray"
options:0
context:@"arrayChanged"];
// This results in observeValueForKeyPath... begin called.
[mao setTheArray:[NSMutableArray array]];
// This results in observeValueForKeyPath... begin called.
[[mao mutableArrayValueForKey:@"theArray"] addObject:@"Zero"];
// These do not results in observeValueForKeyPath...
// begin called, but theArray is changed.
[mao insertObject:@"One" inTheArrayAtIndex:1];
[mao insertObject:@"Two" inTheArrayAtIndex:2];
[mao insertObject:@"Three" inTheArrayAtIndex:3];
// This results in observeValueForKeyPath... begin called.
[[mao mutableArrayValueForKey:@"theArray"] addObject:@"Four"];
[mao removeObserver:mao forKeyPath:@"theArray"];
[mao release];
[pool drain];
return 0;
}
Wenn ich diesen Code ausführe, erhalte ich die folgende Ausgabe:
2011-02-05 17:38:47.724 kvcExperiment\[39048:a0f\] theArray now has 0 items
2011-02-05 17:38:47.726 kvcExperiment\[39048:a0f\] theArray now has 1 items
2011-02-05 17:38:47.727 kvcExperiment\[39048:a0f\] theArray now has 5 items
Ich hatte erwartet, drei weitere Protokollmeldungen zu sehen, die besagen, dass theArray jetzt 2, 3 oder 4 Elemente hat. Ich dachte, der Aufruf von insertObject:inTheArrayAtIndex
sollte dem obvserver mitteilen, dass sich theArray geändert hat, aber in meinem Code ist das nicht der Fall.
Bin ich verwirrt, wenn ich denke, dass insertObject:inTheArrayAtIndex
sollte dazu führen, dass den Beobachtern eine Benachrichtigung übermittelt wird über theArray
? Oder habe ich bei meiner Implementierung etwas übersehen? Für jede Hilfe bin ich dankbar.