如何对KVO使用mutableArrayValueForKey?

时间:2015-12-25 10:09:46

标签: objective-c nsmutablearray nstableview key-value-observing cocoa-bindings

首先:我已经在这里阅读了几次与此问题相关的问题,并且我发布了这个问题,人们可能认为这是一个重复的问题。但我不得不说,作为一个初学者,我没有找到任何有用的信息,所以我希望这个问题能让我和其他人一起做清楚。

我如何理解Bindings& KVC / KVO

考虑一下:我有一个数组(在我的AppDelegate中),一个ArrayController和一个视图元素,比如NSTableView。我已将AppDelegate中的NSMutableArray绑定到ArrayController,而ArrayController又绑定到NSTableView。

在NSTableView中更改某个对象的属性会导致该对象属性的实际更改。到目前为止它的作用。但是,更改NSMutableArray中的内容(例如添加项目)不会更新NSTableView。

我读过的可能的解决方案

我现在已经阅读了多个答案。一个答案似乎表明我不应该向数组本身添加任何东西,而只是添加到ArrayController。我不确定这是否正确,但如果这是一个可能的解决方案,那么获得更多有关如何执行此操作的详细信息会很棒。

其他解决方案提到以下方法:

  
      
  • valueForKey:
  •   
  • valueForKeyPath:
  •   
  • dictionaryWithValuesForKeys:
  •   
  • valueForUndefinedKey:
  •   
  • mutableArrayValueForKey:
  •   

特别是:

  
      
  • mutableArrayValueForKey:
  •   

如何使用mutableArrayValueforKey?

我所做的知道如何在我的应用程序中使用我的数组/中的任何这些方法。 mutableArrayValueForKey方法返回NSMutableArray。我是否必须用这个创建一个新的数组?

现在,我正在做的就是这个。

self.vocabList = [[NSMutableArray alloc] init];

以后,在一个方法中,我正在填充数组:

for (NSObject* o in meaningsArray)
{
    NSLog(@"%@",o);

    Vocab *temp = [[Vocab alloc] init];

    [temp setValue:@"w" forKey:@"word"];
    [temp setValue:@"m" forKey:@"meaning"];

    [self.vocabList insertObject:temp atIndex:[self.vocabList count]];
}

如果到目前为止我所说的一切都是正确的,我的问题是:mutableArrayValueForKey:想要更新NSTabeleView时会进入图片?或者我首先误解了什么?

2 个答案:

答案 0 :(得分:1)

如果要更改数组中的smth并观察更改,则应在此数组的可变代理中进行更改,而不是在数组本身中进行更改。 mutableArrayValueForKey:返回可变代理对象

例如:

我有阵列:

NSMutableArray* selectedIndexPaths;

我添加了观察者:

[self addObserver:self forKeyPath:@"selectedIndexPaths" options:0 context:NULL];

检查更改的方法:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if([keyPath isEqualToString:@"selectedIndexPaths"]) {...}}

更改数组中smth的方法:

- (void)removeObjectFromSelectedIndexPathsAtIndex:(NSUInteger)index{
    NSMutableArray* arr = [self mutableArrayValueForKey:@"selectedIndexPaths"];
    if (arr) [arr  removeObjectAtIndex:index];
}

- (void) addIndexPathToSelected : (NSIndexPath*) object{
NSMutableArray* arr =[self mutableArrayValueForKey:@"selectedIndexPaths"];
if (arr) {
    [arr addObject:object];
}
}

使用转换器:

- (void)removeAllObjects{
    int count = [selectedIndexPaths count];
    for (int i=count-1;i>-1;i--) {
        [self removeObjectFromSelectedIndexPathsAtIndex:i];
    }
}

答案 1 :(得分:0)

简单的解决方案:不要与您的阵列交谈,与您的阵列控制器交谈。而不是[array addObject:…][arrayController addObject:…],而不是[array removeObject:…][arrayController removeObject:…]等。

来自CheshireKat的解决方案:

NSMutableArray *mutableArray = [self mutableArrayValueForKey:@"vocabList"];
for (NSObject* o in meaningsArray)
{
    NSLog(@"%@",o);

    Vocab *temp = [[Vocab alloc] init];

    [temp setValue:@"w" forKey:@"word"];
    [temp setValue:@"m" forKey:@"meaning"];

    [mutableArray insertObject:temp atIndex:[mutableArray count]];
}

另一种解决方案:如果要整个数组,请填充数组并再次设置vocabList

NSMutableArray *mutableArray = [NSMutableArray array];
for (NSObject* o in meaningsArray)
{
    NSLog(@"%@",o);

    Vocab *temp = [[Vocab alloc] init];

    [temp setValue:@"w" forKey:@"word"];
    [temp setValue:@"m" forKey:@"meaning"];

    [mutableArray addObject:temp];
}
self.vocabList = mutableArray;