首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSArrayController和KVO

NSArrayController和KVO
EN

Stack Overflow用户
提问于 2010-01-15 11:55:27
回答 5查看 3K关注 0票数 5

当调用更新底层数组的方法时,我需要做什么来更新绑定到NSArrayController的tableView?举个例子可以说明这一点。

当我的应用程序启动时,它会创建一个SubwayTrain。在初始化SubwayTrain时,它会创建一个SubwayCar。SubwayCar有一个可变的数组'passengers‘。在初始化一辆地铁汽车时,将创建passengers数组,并放入几个People对象(假设一个人的名字是“收票人”,另一个人的名字是“流浪汉”)。这些人总是在SubwayCar上,所以我在初始化时创建它们,并将它们添加到passengers数组中。

在应用程序的生命周期中,人们登上汽车。在SubwayCar上调用'addPassenger‘,并将person作为参数传入。

我有一个与subwayTrain.subwayCar.passengers绑定的NSArrayController,在发布时,我的收票员和流浪汉都很好地出现了。但是当我使用subwayCar addPassenger:时,tableView没有更新。我已经确认了passenger确实添加到了数组中,但gui中没有任何更新。

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

感谢任何愿意帮忙的人。

更新

因此,我可以通过将addPassenger方法从

代码语言:javascript
复制
[seatedPlayers addObject:person];

代码语言:javascript
复制
NSMutableSet *newSeatedPlayers = [NSMutableSet setWithSet:seatedPlayers];

[newSeatedPlayers addObject:sp];

[seatedPlayers release];

[self setSeatedPlayers:newSeatedPlayers];

我猜这是因为我使用的是self setSeatedPlayers。这是正确的做法吗?复制数组、释放旧数组并更新副本似乎非常麻烦(而不是仅仅添加到现有数组中)。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-01-17 10:42:05

因此,我可以通过将addPassenger方法从

seatedPlayers addObject:person;

NSMutableSet *newSeatedPlayer= NSMutableSet setWithSet: seatedPlayers;newSeatedPlayers添加对象:sp;seatedPlayers release;self setSeatedPlayer:newSeatedPlayer;

我猜这是因为我使用的是[self setSeatedPlayers]。这是正确的做法吗?

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

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

您应该做的是实现集合访问器,例如addSeatedPlayersObject:。然后,给自己发一条信息。这使得添加人只是一个简短的一行:

代码语言:javascript
复制
[self addSeatedPlayersObject:person];

只要你关注the KVC-compliant accessor formats,你就会得到免费的KVO通知,就像你使用setSeatedPlayers:一样。

setSeatedPlayers:相比,这种方式的优势在于:

而不是一般的shorter.

  • Because - cleaner.

  • Using - set -

  • notifications.

,它将是特定的集合突变访问器提供了特定集合突变的可能性

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

票数 1
EN

Stack Overflow用户

发布于 2010-01-15 15:41:23

我不知道这是否被认为是一个bug,但是addObject:(和removeObject:atIndex:)不会生成KVO通知,这就是数组控制器/表视图没有更新的原因。要符合KVO,请使用mutableArrayValueForKey:

示例:

代码语言:javascript
复制
[[self mutableArrayValueForKey:@"seatedPlayers"] addObject:person];

您还需要实现insertObject:inSeatedPlayersAtIndex:因为默认的KVO方法非常慢(它们创建一个全新的数组,将对象添加到该数组中,然后将原始数组设置为新数组--效率非常低)

代码语言:javascript
复制
- (void)insertObject:(id)object inSeatedPlayerAtIndex:(int)index
{
   [seatedPlayers insertObject:object atIndex:index];
}

请注意,当数组控制器添加对象时,也会调用此方法,因此它也是一个很好的钩子,用于注册撤消操作等。

票数 7
EN

Stack Overflow用户

发布于 2010-01-16 04:12:46

我还没有尝试过,所以我不能说它有效,但是您不会通过调用以下命令收到KVO通知吗

插入对象:atArrangedObjectIndex:

在ArrayController上?

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2069408

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档