2012-07-23 58 views
1

我试图在我的表视图中包含大中央调度。我有一个属性:NSArray *topPlacesTableView在实现GCD后出现空

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; 
} 

我试图解决的主要问题是,当一个行被选中时,它延续到一个新的表视图。但是当我选择一行时,它会冻结几秒钟,直到新表加载。我希望用户即使在选中该行并准备继续时也能够滚动。任何帮助将不胜感激。

回答

1

要稍微更有效地实现这个作为@Jacob建议,你会做这样的事情(有裁判替换your_table_view_object实际对象):

- (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并从该函数中删除派发队列的创建和释放。要获得更具体的帮助,我们需要看到整个类的实现。

2

您可能会发现这个例子项目有所帮助:https://github.com/akosma/async-uitableview/

+0

如果您有与该问题有关的其他信息,请尝试编辑该问题,而不是下次回答问题:) – 2012-07-24 02:41:32

+0

我还没有销售代表。但是,感谢指针。 – 2012-07-24 05:01:45

1

首先,命名方法开始GET违背Apple's coding guidelines。以get开头的命名方法有一个罕见的特定情况。

您的主要问题是您正在异步调度任务以填充_topPlaces并在异步调用填充之前将其返回。你可以用dispatch_sync替换它,但是你会失去在GCD背景队列上处理任何性能增益。相反,试试这个:

  1. 不要从此方法(void)返回任何
  2. 将您整理了一个级别到downloadrQueue块(不需要跳回主线程尚未 - 排序是昂贵的)
  3. 在你的主队列块,打电话reloadData你的表视图
  4. 在的cellForRowAtIndexPath,填充基于topPlaces你的表

你的第二个问题是,你创建和销毁队列当y你应该坚持下去。尝试将downloadrQueue存储为属性,并在您的表的视图控制器的整个生命周期中保存它。

+0

谢谢@Jacob。我对一些事情感到困惑。对于1.我没有看到我怎么可以让NSArray属性的getter方法什么都不返回。我也想知道如何将downloadrQueue作为一个属性存储(它会是什么类型?)以及为什么这是必要的。 – kkSlider 2012-07-25 00:32:49