如何为 KVO 使用 mutableArrayValueForKey?

How to use mutableArrayValueForKey for KVO?

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

我是如何理解绑定和 KVC / KVO

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

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

我读过的可能的解决方案

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

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

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

特别是:

  • mutableArrayValueForKey:

如何使用 mutableArrayValueforKey?

不知道 但是我知道如何在我的数组/我的应用程序中使用这些方法中的任何一种。 mutableArrayValueForKey 方法 returns 一个 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]];
}

如果到目前为止我所说的一切都是正确的,我的问题是:当想要更新 NSTabeleView 时,mutableArrayValueForKey: 会在哪里出现?还是我一开始就误解了什么?

如果您想更改数组中的 smth 并观察更改,您应该在该数组的可变代理中进行更改,而不是在数组本身中进行更改。 mutableArrayValueForKey: return 可变代理对象.

例如:

我有数组:

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

简单的解决方案:不要与您的阵列对话,与您的阵列控制器对话。代替 [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;