0

次のコードがあります。

dispatch_async(dispatch_get_global_queue(0, 0), ^
{
    [self loadThumbnails]; //loads an array of photos which get loaded into each table cell
    [self performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
});

私のサブクラスのイニシャライザでUITableView。これらのサムネイルは読み込みに時間がかかるため、これらのサムネイルを別のスレッドでテーブルに読み込みたいと思います。それでも、上記のコードを実行すると、テーブルビューが空白になります。だから私の最初の質問は、どうすればこれを修正できますか?

2 番目の質問は、テーブルビュー オブジェクトが解放されたら、このディスパッチ キューを強制終了したいということです。これは可能ですか / これはどのように達成されますか?

Vikings のソリューションを実装してみましたが、これが得られたものです。

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    static NSString *cellIdentifier = @"ThumbnailCell";
    UITableViewCell *tableViewCell = [self dequeueReusableCellWithIdentifier:cellIdentifier];    

    if (!tableViewCell)
    {
        tableViewCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
    }


    NSInteger thumbnailsPerCell = self.thumbnailViewsPerCell;
    NSInteger startingThumbnailIndex = indexPath.row * thumbnailsPerCell;
    NSInteger totalThumbnails = MIN(((indexPath.row * thumbnailsPerCell) + thumbnailsPerCell) , [self.thumbnailViews count]) - startingThumbnailIndex;

    if ([tableViewCell.contentView subviews])
    {
        for (UIView *subview in [tableViewCell.contentView subviews]) 
        {
            [subview removeFromSuperview];
        }
    }

    for (int i = 0; i < totalThumbnails; i++)
    {
        UIView *thumbnailView = [[UIView alloc] initWithFrame:CGRectMake(i * self.cellDimension, 0, self.cellDimension, self.cellDimension)];
        UIView *thumbnail = [[self.thumbnailCache objectForKey:[NSNumber numberWithInt:i]] retain];
        if (thumbnail)
        {
            [thumbnailView addSubview:thumbnail];
            [tableViewCell.contentView addSubview:thumbnailView];
            [thumbnailView release];
            [thumbnail release];
        }
        else 
        {
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), 
            ^{
                UIView *thumbnail = [[self createThumbnailAtIndex:i] retain];

                if (thumbnail)
                {
                    dispatch_async(dispatch_get_main_queue(), 
                    ^{
                        UITableViewCell *tableViewCell = [self cellForRowAtIndexPath:indexPath];

                        if (tableViewCell)
                        {
                            [thumbnailView addSubview:thumbnail];
                            [tableViewCell.contentView addSubview:thumbnailView];
                            [thumbnailView release];
                            [thumbnail release];
                        }
                    });

                    [self.thumbnailCache setObject:thumbnail forKey:[NSNumber numberWithInt:i]];
                }
            });
        }
    }

    return tableViewCell;
}

これにより、空の tableView が生成されます。理由の手がかりはありますか?

4

3 に答える 3

1

私は同じ問題を抱えていましたが、完全に解決しました。以下のスレッドを確認してください。画像を別のスレッドにロードするだけです。これは遅延ロードと呼ばれる手法です。

テーブル ビューの非同期スクロール

于 2012-10-16T01:29:46.123 に答える
1

GCD と performSelector を混在させるのはちょっと奇妙です。私はこのようにします:

dispatch_async(dispatch_get_global_queue(0, 0), ^
{
    [self loadThumbnails]; //loads an array of photos which get loaded into each table cell
    dispatch_async(dispatch_get_main_queue(), ^ {
        [self reloadData];
    });
});
于 2012-10-15T23:24:58.323 に答える
0

2 番目の質問への回答: テーブルのすべてのサムネイルを読み込むべきではないかもしれません。個別のリクエストで表示する必要があるものをロードするだけです。セルがサムネイル画像を変更した場合は、以前のリクエストをキャンセルすることもできます。SBWebImageのようにすべてを行うライブラリもあります。

于 2012-10-15T23:21:06.190 に答える