[英]UITableViewDataSource load asynchronously
我有一个UITableView
,应将条目划分为多个部分 。 数据需要一些时间来处理,因此它是这样完成的:
@interface AsyncTable()
NSMutableArray* _alphaKeys;
@end
@implementation AsyncTable
-(void)refreshData {
dispatch_async(_serialQueue, ^{
<load of the _alphaKeys>
dispatch_async(dispatch_get_main_queue(), ^{
[table reloadData];
});
});
}
...
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [_alphaKeys count];
}
...
@end
现在,这是第一次完美运行。
但是我的数据有时会更改,因此我从通知中调用方法refreshData。 而且它开始崩溃,例如在执行numberOfSectionsInTableView
时以及在cellForRowAtIndexPath
,数组可能具有对不同内容的引用。
时间问题在于时序,我们假设彼此之间紧接有2个调用:第一个调用已完成在主线程中加载和调度reloadData,然后第二个请求到来并在主线程被调用之前开始重新加载数据...
任何建议如何解决这个问题? 我不想将所有内容都放在主线程中(它起作用了,我现在正在尝试重构应用程序以使其更具反应性)
您的问题是由在加载tableView的同时更新数据源( _alphaKeys
)引起的。 UITableView是异步加载的,无法知道何时完成。 但是,如果您更改数据源并立即调用reloadData,即使加载正在进行,它也将做正确的事情。 技巧是必须在主线程上完成对数据的更改。
我对您的回答是更改代码,以便后台线程对数据的一个副本进行处理。 处理完成后,在主线程上运行一个块,将新数据复制到表视图的数据源,然后立即调用reloadData
。
请参阅我对示例代码的修改:
@interface AsyncTable()
NSArray* _alphaKeys; // <-- copy for data source is immutable
@end
@implementation AsyncTable
-(void)refreshData {
dispatch_async(_serialQueue, ^{
NSMutableArray *alphaKeysCopy = [_alphaKeys mutableCopy]; // <-- Create a new array if processing does not require current state
<load of the alphaKeysCopy>
dispatch_async(dispatch_get_main_queue(), ^{
_alphaKeys = [alphaKeysCopy copy]; // <-- Copy on the main thread so the table view can't see an intermediate state
[table reloadData];
});
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.