我正在尝试将盛大的中央调度合并到我的表格视图中。我有一个属性:NSArray *topPlaces
topPlaces
是来自Flickr查询的字典数组。这需要一些时间来执行,所以我想把它放在一个单独的线程上。此表使用topPlaces
填写表的每一行(注意:此表是加载应用程序时显示的第一个视图)。因为有几个方法调用了getTopPlaces,所以在topPlaces未初始化的情况下,我在getTopPlaces中进行了一个惰性实例化。我的代码目前:
- (NSArray *)getTopPlaces
{
if (!_topPlaces)
{
dispatch_queue_t downloadrQueue = dispatch_queue_create("lister downloader", NULL);
dispatch_async(downloadrQueue, ^{
_topPlaces = [FlickrFetcher topPlaces];
dispatch_async(dispatch_get_main_queue(), ^{
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"_content" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *flickrTopPlacesAlphabetic = [_topPlaces sortedArrayUsingDescriptors:sortDescriptors];
_topPlaces = flickrTopPlacesAlphabetic;
});
});
dispatch_release(downloadrQueue);
}
return _topPlaces;
}
我试图解决的主要问题是,当选择一行时,它会转移到新的表视图。但是当我选择一行时,它会冻结几秒钟,直到新表加载为止。我希望用户能够在选择行并准备segue时滚动。任何帮助将不胜感激。
答案 0 :(得分:2)
您可能会发现此示例项目很有用:https://github.com/akosma/async-uitableview/
答案 1 :(得分:1)
首先,以get开头的命名方法与Apple's coding guidelines相反。对于以get开头的命名方法,有一个罕见且具体的案例。
您的主要问题是您异步调度任务以填充_topPlaces并在异步调用填充它之前返回它。您可以使用dispatch_sync替换它,但是您将失去在GCD后台队列上处理的任何性能增益。相反,试试这个:
你的第二个问题是,当你应该坚持下去时,你正在创建和销毁队列。尝试将downloadrQueue存储为属性并将其保留在表的视图控制器的生命周期中。
答案 2 :(得分:1)
为了更有效地实现这一点,@Jacob建议您执行类似的操作(将your_table_view_object替换为实际对象的ref):
- (void)updateTopPlaces
{
if (!_topPlaces)
{
dispatch_queue_t downloadrQueue = dispatch_queue_create("lister downloader", NULL);
dispatch_async(downloadrQueue, ^{
_topPlaces = [FlickrFetcher topPlaces];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"_content" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *flickrTopPlacesAlphabetic = [_topPlaces sortedArrayUsingDescriptors:sortDescriptors];
_topPlaces = flickrTopPlacesAlphabetic;
dispatch_async(dispatch_get_main_queue(), ^{
[your_table_view_object reloadData];
});
});
dispatch_release(downloadrQueue);
}
}
要完成他的建议,您将创建一个类型为dispatch_queue_t的实例变量,并从此函数中删除调度队列的创建和释放。有关此更具体的帮助,我们需要查看整个类的实现。