Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 表视图会混淆图像_Iphone_Ios_Uitableview_Sdwebimage - Fatal编程技术网

Iphone 表视图会混淆图像

Iphone 表视图会混淆图像,iphone,ios,uitableview,sdwebimage,Iphone,Ios,Uitableview,Sdwebimage,我使用在TableView中加载和显示异步图像。但有时当我快速上下滚动时,它会混合所有图像并显示在其他行中。这是我的cellForRowAtIndexPath: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; CustomTable

我使用在TableView中加载和显示异步图像。但有时当我快速上下滚动时,它会混合所有图像并显示在其他行中。这是我的cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

        cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

    } 

// Configure the cell.

MWFeedItem *item = [itemsToDisplay objectAtIndex:indexPath.row];

if (item) {


        // Parse out Image URL for cell

        if (cell.imageView.image == nil) {

        NSError *error = NULL;

        NSRegularExpression *regexImage = [NSRegularExpression regularExpressionWithPattern:@"(<img\\s[\\s\\S]*?src\\s*?=\\s*?['\"](.*?)['\"][\\s\\S]*?>)+?"

                                                                               options:NSRegularExpressionCaseInsensitive

                                                                                error:&error];
        [regexImage enumerateMatchesInString:item.content

                                options:0

                                  range:NSMakeRange(0, [item.content length])

                             usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {



                                 NSString *src = [item.content substringWithRange:[result rangeAtIndex:2]];

                                 NSLog(@"img src: %@", src);

                                 [cell.imageView setImageWithURL:[NSURL URLWithString:src]];

                             }];}



        if (cell.imageView.image  == nil) {

            cell.imageView.image = [UIImage imageNamed:@"video.png"];

}

    return cell;

}

我不知道怎么了,但我想这是因为我在单元格中解析图像,但速度不够快,所以它会一次又一次地启动。你能告诉我如何解决这个问题吗?

我相信,高层次的答案是,当你滚动时,你是在完成将图像放入单元格之前重复使用单元格。不管怎样,当我在代码中看到这一点时,这就是它的含义

我不使用SDWebImage,也不知道setImageWithURL变体是什么,但github网页有一个“如何使用”的说明,可以在图像获取成功或失败时给它一个完成块来执行。 因此,当您最终获得图像时,但在将其放入UITableViewCell之前,您需要检查该单元格是否仍被分配给与开始获取图像时相同的indexPath。由于setImageWithURL似乎总是设置图像,因此您必须将临时UIImageView放置在单元格中,而不是直接放置在单元格中。我查看的文档有一个方法调用,其中包含placeholder image:和completed:两个选项,使用它们可以执行类似于未检查编译器的代码:

// before you go off to get the image, save the indexPath of the cell
NSIndexPath *originalIndexPath = indexPath;
UIImageView *tempImageView;
[tempImageView setImageWithURL:[NSURL URLWithString : [NSURL URLWithString:src]]
           placeholderImage:[UIImage imageNamed:@"placeholder.png"]
                  completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
    // completion block
    // You probably want to check that it really succeeded, but if it did
    // Now you have an image in the image parameter and probably in tempImageView.
    // Check to see if the cell is still at the original indexPath
    // If so, put the image in.
    // If not, the row was scrolled out of sight and the cell has been reused
    // so just drop the image on the floor -- it is no longer useful
    NSIndexPath *currentIndexPath = [self.tableview indexPathForCell:cell]
    if ([currentIndexPath isEqual originalIndexPath]) {
        cell.imageView.image = image;
        // or perhaps: cell.imageView.image = tempImageView.image;
    }
}];

高层次的答案是,我相信,当你滚动时,你是在把图像放入细胞之前重用细胞。不管怎样,当我在代码中看到这一点时,这就是它的含义

我不使用SDWebImage,也不知道setImageWithURL变体是什么,但github网页有一个“如何使用”的说明,可以在图像获取成功或失败时给它一个完成块来执行。 因此,当您最终获得图像时,但在将其放入UITableViewCell之前,您需要检查该单元格是否仍被分配给与开始获取图像时相同的indexPath。由于setImageWithURL似乎总是设置图像,因此您必须将临时UIImageView放置在单元格中,而不是直接放置在单元格中。我查看的文档有一个方法调用,其中包含placeholder image:和completed:两个选项,使用它们可以执行类似于未检查编译器的代码:

// before you go off to get the image, save the indexPath of the cell
NSIndexPath *originalIndexPath = indexPath;
UIImageView *tempImageView;
[tempImageView setImageWithURL:[NSURL URLWithString : [NSURL URLWithString:src]]
           placeholderImage:[UIImage imageNamed:@"placeholder.png"]
                  completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
    // completion block
    // You probably want to check that it really succeeded, but if it did
    // Now you have an image in the image parameter and probably in tempImageView.
    // Check to see if the cell is still at the original indexPath
    // If so, put the image in.
    // If not, the row was scrolled out of sight and the cell has been reused
    // so just drop the image on the floor -- it is no longer useful
    NSIndexPath *currentIndexPath = [self.tableview indexPathForCell:cell]
    if ([currentIndexPath isEqual originalIndexPath]) {
        cell.imageView.image = image;
        // or perhaps: cell.imageView.image = tempImageView.image;
    }
}];

将单元格标识符从更改为

static NSString *CellIdentifier = @"Cell"; 


将单元格标识符从更改为

static NSString *CellIdentifier = @"Cell"; 


setImageWithURL是由SDWebImage指定的方法。你能告诉我上面的代码放在哪里吗?好的,我简单地看了SDWebImage并编辑了我的答案。您需要自己将图像放入单元格中,但前提是单元格未被重用。关于如何将其用于tableview的简单示例是错误的,因为它正是您遇到的问题。每当您使用TableView进行异步图像处理时,您都需要进行此类检查,以确保单元格仍然具有相同的标识,即滚动不会导致单元格被取消分配,然后可能被重新使用。感谢您为此所做的努力。如果[currentIndexPath isEqual originalIndexPath]中说必须有一个:before,我会在该行中得到一个错误originalIndexPath@Supporter_04尝试按照错误提示插入冒号:[currentIndexPath isEqual:originAlinIndexPath]对不起,我有点傻:P。如你所见,我使用了上面的答案,因为它只有一行@CharliePrice非常感谢您的努力SetImageWithURL是SDWebImage指定的一种方法。你能告诉我上面的代码放在哪里吗?好的,我简单地看了SDWebImage并编辑了我的答案。您需要自己将图像放入单元格中,但前提是单元格未被重用。关于如何将其用于tableview的简单示例是错误的,因为它正是您遇到的问题。每当您使用TableView进行异步图像处理时,您都需要进行此类检查,以确保单元格仍然具有相同的标识,即滚动不会导致单元格被取消分配,然后可能被重新使用。感谢您为此所做的努力。如果[currentIndexPath isEqual originalIndexPath]中说必须有一个:before,我会在该行中得到一个错误originalIndexPath@Supporter_04尝试按照错误提示插入冒号:[currentIndexPath isEqual:originAlinIndexPath]对不起,我有点傻:P。如你所见,我使用了上面的答案,因为它只有一行@查理·普莱斯非常感谢您的邀请effort@Supporter_04,这可能会起作用,但在我看来,它似乎为每个数据项创建了一个新的单元格,因此您不会得到任何单元格重用。这会降低UITableView的内存效率。Charlie的答案可能更难实现您需要正确理解SDWebImage的细节,但它尊重单元重用的原则。当然,这不是性能的最佳解决方案,但我认为他需要快速解决方案:@Supporter_04,这可能行得通,但在我看来,它似乎为每个数据项创建了一个新单元,所以你没有得到任何细胞重复使用。这会降低UITableView的内存效率。查理的答案可能更难实现,你会的
需要正确理解SDWebImage的细节,但它尊重单元重用原则。当然,这不是性能的最佳解决方案,但我认为他需要快速解决方案: