当调用方法来更新基础数组时,我需要做什么来更新绑定(bind)到NSArrayController的tableView?一个例子可以澄清这一点。

当我的应用程序启动时,它会创建一个SubwayTrain。初始化SubwayTrain时,它将创建一个SubwayCar。 SubwayCar具有可变的数组“passengers”。初始化Subway车时,将创建乘客数组,并放入几个People对象(假设一个名为“票务收集者”的人和另一个名为“无家可归的人”的人)。这些家伙总是在SubwayCar上,所以我在初始化时创建它们,并将它们添加到乘客阵列中。

在应用程序的生命周期中,人们会上车。在SubwayCar上调用“addPassenger”,并将传入的人作为参数。

我有一个绑定(bind)到metroTrain.subwayCar.passengers的NSArrayController,并且在启动时,我的票务收集器和无家可归的家伙出现得很好。但是当我使用[subwayCar addPassenger:]时,tableView不会更新。我已经确认将旅客肯定添加到了数组中,但是gui中没有任何更新。

我可能做错了什么?我的直觉是,它与KVO有关-调用addPassenger时,数组 Controller 不知道更新(即使addPassenger调用[passengers addObject:]。在这里我可能会出错-如果有帮助,我可以发布代码。

感谢任何愿意提供帮助的人。

更新

因此,事实证明,我可以通过更改以下内容的addPassenger方法来使其工作

[seatedPlayers addObject:person];


NSMutableSet *newSeatedPlayers = [NSMutableSet setWithSet:seatedPlayers];

[newSeatedPlayers addObject:sp];

[seatedPlayers release];

[self setSeatedPlayers:newSeatedPlayers];

我猜这是因为我正在使用[self setSeatedPlayers]。这是正确的方法吗?复制阵列,释放旧阵列并更新副本似乎非常麻烦(与仅添加到现有阵列相反)。

最佳答案



首先,是冒号的setSeatedPlayers:。这在Objective-C中至关重要。

使用自己的 setter 是正确的方法,但是您使用的方法不正确。它可以工作,但是您编写的代码仍然比您需要的更多。

您应该执行的是实现集合访问器,例如addSeatedPlayersObject:。然后,向自己发送该消息。这使得添加人员成为一小段话:

[self addSeatedPlayersObject:person];

只要您遵循the KVC-compliant accessor formats,就可以像setSeatedPlayers:一样免费获得KVO通知。

setSeatedPlayers:相比,它的优点是:
  • 用于更改集合的代码将更短。
  • 因为它更短,所以会更干净。
  • 使用特定的集合变异访问器可提供特定的集合变异KVO通知,而不是一般的“整个组设置已更改”通知。

  • 为了简洁起见,我也更喜欢这种解决方案,而不是mutableSetValueForKey:,因为很容易将字符串文字中的键拼写错误。 (Uli Kusterer has a macro to cause a warning when that happens,当您确实需要与KVC或KVO本身进行交谈时,它很有用。)

    10-08 05:52