当调用更新底层数组的方法时,我需要做什么来更新绑定到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方法从
[seatedPlayers addObject:person];至
NSMutableSet *newSeatedPlayers = [NSMutableSet setWithSet:seatedPlayers];
[newSeatedPlayers addObject:sp];
[seatedPlayers release];
[self setSeatedPlayers:newSeatedPlayers];我猜这是因为我使用的是self setSeatedPlayers。这是正确的做法吗?复制数组、释放旧数组并更新副本似乎非常麻烦(而不是仅仅添加到现有数组中)。
发布于 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:。然后,给自己发一条信息。这使得添加人只是一个简短的一行:
[self addSeatedPlayersObject:person];只要你关注the KVC-compliant accessor formats,你就会得到免费的KVO通知,就像你使用setSeatedPlayers:一样。
与setSeatedPlayers:相比,这种方式的优势在于:
而不是一般的shorter.
,它将是特定的集合突变访问器提供了特定集合突变的可能性
与mutableSetValueForKey:相比,我更喜欢这种解决方案,这既是为了简洁,也是因为它很容易将字符串中的键拼写错误。(Uli Kusterer has a macro to cause a warning when that happens,当您确实需要与KVC或KVO本身对话时,它很有用。)
发布于 2010-01-15 15:41:23
我不知道这是否被认为是一个bug,但是addObject:(和removeObject:atIndex:)不会生成KVO通知,这就是数组控制器/表视图没有更新的原因。要符合KVO,请使用mutableArrayValueForKey:
示例:
[[self mutableArrayValueForKey:@"seatedPlayers"] addObject:person];您还需要实现insertObject:inSeatedPlayersAtIndex:因为默认的KVO方法非常慢(它们创建一个全新的数组,将对象添加到该数组中,然后将原始数组设置为新数组--效率非常低)
- (void)insertObject:(id)object inSeatedPlayerAtIndex:(int)index
{
[seatedPlayers insertObject:object atIndex:index];
}请注意,当数组控制器添加对象时,也会调用此方法,因此它也是一个很好的钩子,用于注册撤消操作等。
发布于 2010-01-16 04:12:46
我还没有尝试过,所以我不能说它有效,但是您不会通过调用以下命令收到KVO通知吗
插入对象:atArrangedObjectIndex:
在ArrayController上?
https://stackoverflow.com/questions/2069408
复制相似问题