2012-07-23 57 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