2013-05-01 65 views
1

我想用uiimage-from-animated-gif加载一些GIF到我的UITableView单元格。但问题是,每次我尝试从我的缓存中加载图像时,单元格在它滚动之前停止一会儿。UIImageView滚动暂停一秒

这是我用

postGif = (UIImageView *)[cell viewWithTag:104]; 

if ([[ImageCache sharedImageCache] DoesExist:post[@"gif"]] == true) 
{ 
    image = [[ImageCache sharedImageCache] GetImage:post[@"gif"]]; 

    postGif.image = [UIImage animatedImageWithAnimatedGIFData:image]; 

}else 
{ 
    dispatch_queue_t backgroundQueue = dispatch_queue_create("cacheImage", 0); 

    dispatch_async(backgroundQueue, ^{ 

     NSData *imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:post[@"gif"]]]; 
     dispatch_async(dispatch_get_main_queue(), ^{ 

      // Add the image to the cache 
      [[ImageCache sharedImageCache] AddImage:post[@"gif"] image:imageData]; 

      NSIndexPath* ind = [NSIndexPath indexPathForRow:0 inSection:indexPath.section]; 
      [self.feedTableView beginUpdates]; 
      [self.feedTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:ind] withRowAnimation:UITableViewRowAnimationNone]; 
      [self.feedTableView endUpdates]; 
     }); 
    }); 
} 

postGif.layer.cornerRadius = 2.0; 
postGif.layer.masksToBounds = YES; 

[cell.contentView addSubview:postGif]; 

我试图背景队列以及代码。但图像加载速度非常慢。

if ([[ImageCache sharedImageCache] DoesExist:post[@"gif"]] == true) 
{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 
              (unsigned long)NULL), ^(void) { 
     NSData *image = [[ImageCache sharedImageCache] GetImage:post[@"gif"]]; 

     postGif.image = [UIImage animatedImageWithAnimatedGIFData:image]; 
    }); 

}else 
{ 
    dispatch_queue_t backgroundQueue = dispatch_queue_create("cacheImage", 0); 

    dispatch_async(backgroundQueue, ^{ 

     NSData *imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:post[@"gif"]]]; 
     dispatch_async(dispatch_get_main_queue(), ^{ 

      // Add the image to the cache 
      [[ImageCache sharedImageCache] AddImage:post[@"gif"] image:imageData]; 

      NSIndexPath* ind = [NSIndexPath indexPathForRow:0 inSection:indexPath.section]; 
      [self.feedTableView beginUpdates]; 
      [self.feedTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:ind] withRowAnimation:UITableViewRowAnimationNone]; 
      [self.feedTableView endUpdates]; 
     }); 
    }); 
} 

我不知道我做错了什么。也许我没有理解一个概念。

Maycoff建议我不应该从后台队列中修改用户界面对象(如UIImageView)的属性,并且需要在后台队列上创建UIImage实例,有人可以向我解释它是什么我不是在抓?

感谢您的帮助提前。

回答

6

您之前的代码中的问题是,您正在主队列上的GIF数据中创建UIImage。由于解码GIF(特别是具有多个帧的GIF)可能需要一些时间,因此您正在阻塞主线程,这就是为什么每次需要显示其他图像时表视图停止滚动的原因。

您后面的代码中的问题是,您正在修改背景队列上UIImageViewimage属性。您只能修改主队列上的用户界面对象。

您需要做的是在后台队列上创建UIImage,然后调度回主队列以更新UIImageViewimage属性。因此:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 
             (unsigned long)NULL), ^(void) { 
    NSData *data = [[ImageCache sharedImageCache] GetImage:post[@"gif"]]; 
    UIImage *image = [UIImage animatedImageWithAnimatedGIFData:data]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     postGif.image = image; 
    } 
}); 
+0

这使得现在更有意义:)非常感谢。但即使现在我也不确定为什么它会暂时冻结。 – sankaet 2013-05-01 06:28:54

+0

它适合我这样的完美。确保你在后台线程上执行所有的图像处理,并在主线程上执行postGif.image = image。如果您将任何图像处理粘贴到主线上,它将随机冻结滚动。 – TrekOnTV2017 2013-10-28 21:47:01