mar*_*eed 0 cocoa objective-c nstableview nsarraycontroller
我正在初始化一个简单的接口,NSTableView绑定到一个数组控制器(管理一个字典数组).我想在后台加载数组的内容(这是一个非常耗时的过程),每100或1000个元素更新表视图.我们的想法是界面可用且响应迅速.我无法弄清楚如何在之后触发更新/刷新.桌子仍然是空的.任何人都可以提供指针吗?
我目前的做法是:
// In init for my app controller. This seems to work well, but I've tried other methods here.
[self performSelectorInBackground:@selector(loadTable) withObject:nil];
- (void)loadTable {
tracks = [[NSMutableArray alloc] initWithCapacity:[masters count]];
// ... create each object one-by-one. Add it to tracks.
for (... in ...) {
[tracks addObject:newObject];
}
// Now I don't know what to do next. The table remains empty.
// Things I've tried (though possibly not in all combinations with the
// method above):
// 1. With a suitably-defined reloadData method, which just reloads
// the table view and sets needs display.
[self performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
// 2. Reload directly.
[tv reloadData];
[tv setNeedsDisplay];
}
Run Code Online (Sandbox Code Playgroud)
如果我只是直接加载数据,并且不尝试在后台执行此操作,一切正常,但需要将近30秒.
你有一个表列(我假设你的意思)绑定到一个数组控制器,所以这是表视图从中获取数据的地方.表视图可能很好地要求更新的数组,但它要求数组控制器,它不知道任何变化.
阵列控制器不会简单地转过身来询问您的新数据; 这意味着它只是为了让你更难将表视图绑定到你的数组,而事实并非如此.这是一个控制器; 它的工作是拥有(复制)数组并维护其顺序和用户选择其对象的某个子集.
因此,您需要阵列控制器来查找何时向阵列添加项目.实现此目的的最佳方法是将阵列控制器绑定到控制器的contentArray
属性,并以符合KVO的方式更新该属性.
这意味着:
init
方法中创建可变数组.(当然,发布它dealloc
.)addTracksObject:
和removeTracksObject:
(在技术上set访问方法,所以国际志愿者组织会忽略他们的一个数组属性),为您提供方便.addTracksObject:
消息.你应该通过向自己发送一条insertObject:inTracksAtIndex:
消息来响应([self countOfTracks]
除了你想做一个insort之外的索引),你应该insertObject:inTracksAtIndex:
通过向你的tracks
阵列发送insertObject:atIndex:
消息来回应.正如我所提到的,KVO将忽略addFooObject:
并且removeFooObject:
何时foo
是NSArray属性,考虑到那些只有NSSet属性访问器,因此您需要在它们之上实现它们insertObject:inFooAtIndex:
,removeObjectFromFooAtIndex:
因为它们是数组访问器,这意味着KVO将对它们作出反应.
正如我刚才描述的那样,第3步将非常缓慢,因为它将导致阵列控制器重新获取您的属性和表视图,以便arrangedObjects
为您添加的每一行至少重新获取一次阵列控制器.
因此,您应该使用此备用步骤3维护批量添加行为:
insertTracks:atIndexes:
并传递一组(例如,100或1000)轨道和由其形成的索引集的数组[NSIndexSet indexSetWithRange:(NSRange){ [self countOfTracks], countOfBatch }]
.您还需要实现removeTracksAtIndexes:
,因为如果您没有对应的KVO将忽略每个插入方法.您可能应该将阵列控制器设置为尝试保留选择,以便在您仍然引入行时不会过多地挫败用户.
此外,您可能希望在后台线程上创建对象,定期向自己发送另一批使用主线程执行添加的批处理.我通常会主动在主线程运行循环中做事情,但是当你的定期加载构建另一批时,这种事情很容易让你的界面变得迟钝.
归档时间: |
|
查看次数: |
1636 次 |
最近记录: |