1

テーブルビューにグランドセントラルディスパッチを組み込んでいます。私はプロパティを持っています:NSArray *topPlaces

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

私が解決しようとしている主な問題は、行が選択されると、新しいテーブルビューに移動することです。しかし、行を選択すると、新しいテーブルが読み込まれるまで数秒間フリーズします。行が選択されてセグエの準備をしている間でも、ユーザーがスクロールできるようにしたいと思います。どんな助けでも大歓迎です。

4

3 に答える 3

2

このサンプルプロジェクトが役立つ場合があります:https ://github.com/akosma/async-uitableview/

于 2012-07-24T01:13:50.587 に答える
1

まず、getで始まる命名方法は、Appleのコーディングガイドラインに違反します。getで始まるメソッドの命名には、まれで特定のケースがあります。

主な問題は、タスクを非同期でディスパッチして_topPlacesにデータを入力し、非同期呼び出しでデータを入力する前にタスクを返すことです。これをdispatch_syncに置き換えることもできますが、そうすると、GCDバックグラウンドキューでの処理によるパフォーマンスの向上が失われます。代わりに、これを試してください:

  1. このメソッドから何も返さないでください(void)
  2. 並べ替えをレベルを上げてdownloadrQueueブロックに移動します(まだメインスレッドに戻る必要はありません-並べ替えにはコストがかかります)
  3. メインキューブロックで、テーブルビューでreloadDataを呼び出します
  4. cellForRowAtIndexPathで、topPlacesに基づいてテーブルにデータを入力します

2番目の問題は、キューを保持する必要があるときにキューを作成および破棄していることです。downloadrQueueをプロパティとして保存し、テーブルのViewControllerの存続期間中保持してみてください。

于 2012-07-24T02:34:42.330 に答える
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型のインスタンス変数を作成し、この関数からディスパッチキューの作成と解放を削除します。これに関するより具体的なヘルプについては、クラスの実装全体を確認する必要があります。

于 2012-07-25T08:55:27.023 に答える