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。我希望表格将这些缩略图加载到单独的线程上,因为它们需要一些时间来加载。然而,当我执行上面的代码时,tableview 出现空白。所以我的第一个问题是如何解决这个问题?

我的第二个问题是,我希望在释放 tableview 对象后终止这个调度队列。这可能/如何实现?

尝试实施 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

It's kind of strange to mix GCD with performSelector. I would do it this way:

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 回答
1

I had the same issue, and solved it perfectly, check the thread below. Just load the images in a separate thread, a technique referred to as lazy loading.

Table View Scrolling Async

于 2012-10-16T01:29:46.123 回答
0

answering your second question: maybe you shouldn't load all thumbnails for your table. Just load those ones you need to display in separate requests. You could even cancel previous requests if cell has changed the thumbnail image. There are even libraries which do everything for you like SBWebImage

于 2012-10-15T23:21:06.190 回答