2011-02-05 43 views
4

我有一個綁定到陣列控制器的模型。我需要能夠直接更新模型並將更新發送到陣列控制器。在我的搜索中,我發現我可以在我的模型上使用mutableArrayValueForKey:並通過返回的NSMutableArray進行更新。在insertObject時應該通知觀察者:在<Key> AtIndex:被調用?

我還發現幾個引用使我相信,如果我實現並使用符合KVC的getter和mutable索引訪問器,我也可以更新模型併發送通知。在我的代碼,我實現

-countOf<Key>: 
-objectIn<Key>AtIndex: 
-insertObject:in<Key>AtIndex: 
-removeObjectFrom<Key>AtIndex: 

調用insertObject:in<Key>AtIndex:沒有造成我的觀察被通知。下面的代碼是我能想出來測試我想要做的最小的一件事。

#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; 
} 

當我運行這段代碼我得到以下輸出:

 
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 

我期待看到說theArray現在有2個,3個或4個項目三個日誌消息。我認爲調用insertObject:inTheArrayAtIndex應該已經通知obvserver該數組已經改變,但在我的代碼中不是。

我在困惑中認爲insertObject:inTheArrayAtIndex應該導致通知被髮送給theArray觀察員?或者,我在執行中錯過了什麼?任何幫助表示讚賞。

回答

9

這是因爲你沒有實現insert和remove方法。

「什麼!」,你說。 「我也是!」

不,不是。幾乎,但你得到一個錯誤的:它的removeObjectFromTheArrayAtIndex:

應用該修復後,所有六個更改都會導致觀察者通知。

相關問題