如何异步从服务器检索图像

时间:2013-05-03 05:41:50

标签: objective-c

我有一个NSMutableArray带有一些图片网址。图像大小在12KB到6MB之间。我使用AsycImageView类并实现但是当大图像下载应用程序崩溃时,我在该类中为maxsize提供了6 * 1024 * 1024(6MB),将时间间隔增加到60.0秒到180.o秒,但是有没用。我收到错误“收到内存警告”,当应用程序崩溃时自动连接从设备中删除,但在模拟器中没有崩溃。

5 个答案:

答案 0 :(得分:3)

您可以使用multiThreading执行此操作。这是一个代码

- (UIImageView *)getImageFromURL:(NSDictionary *)dict
{
    #ifdef DEBUG
    NSLog(@"dict:%@", dict);
    #endif

    UIImageView *_cellImage = nil;
    _cellImage = ((UIImageView *)[dict objectForKey:@"image"]);
    NSString *strURL = [dict objectForKey:@"imageurl"]);

    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];

    #ifdef DEBUG
    NSLog(@"%i", data.length);
    #endif

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *dataFilePath = [NSString stringWithFormat:@"%@.png", [documentsDirectory stringByAppendingPathComponent:[dict objectForKey:@"imageid"]]];

    if (data) // i.e. file exist on the server
    {
        [data writeToFile:dataFilePath atomically:YES];
        _cellImage.image = [UIImage imageWithContentsOfFile:dataFilePath];
    }
    else // otherwise show a default image.
    {
        _cellImage.image = [UIImage imageNamed:@"nouser.jpg"];
    }
    return _cellImage;
}

并在cellForRowAtIndexPath中调用此方法,如下所示:

    NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:imageURL, @"imageurl", self.imgPhoto, @"image", imageid, @"imageid", nil];
    [NSThread detachNewThreadSelector:@selector(getImageFromURL:) toTarget:self withObject:dict];

代码将开始在多个线程中获取图像,并将图像本地保存到文档文件夹。如果已存在具有相同名称的图像,则不会再次下载该图像。希望这有帮助

答案 1 :(得分:3)

GCD使用lazy loading

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
 dispatch_async(queue, ^{
       NSString *strURL = url here;
       NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
       UIImage *image = nil;
       if(data)
        image = [UIImage imageWithData:data];
      dispatch_sync(dispatch_get_main_queue(), ^{
           //now use image in image View  or anywhere according to your requirement.
           if(image)
             yourImgView = image
      });
 });

答案 2 :(得分:1)

您可以使用GCD异步下载图像。使用以下代码

__block NSData *imageData;

dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, NULL);
dispatch_async(myQueue, ^{
  //load url image into NSData
  imageData = [NSData dataWithContentsOfURL: your_image_URL];
  if(imageData) {
    dispatch_sync(dispatch_get_main_queue(), ^{
        //convert data into image after completion
        UIImage *img = [UIImage imageWithData:imageData];
        //do what you want to do with your image
    });
 } else {
      NSLog(@"image not found at %@", your_image_URL);
 }
});
dispatch_release(myQueue);

有关详细信息,请参阅dispatch_queue_t

答案 3 :(得分:0)

我建议放弃替换API SDWebImage它为UIImageVIew提供了一个类别,支持来自网络的远程图像。你也可以有一个占位符图像,直到异步下载图像 。它易于使用,节省了大量工作

答案 4 :(得分:0)

您的问题似乎更多是内存使用问题,而不是性能问题。

如果您真的想要异步下载图片,我建议您使用UIImageView category中的AFNetworking,该Leaks Instrument已经过全面测试并且维护得非常好。

但是在这里你会在设备上遇到内存警告(显然它比你在Mac上运行的模拟器的内存要少得多)。

所以我首先使用静态分析器:

enter image description here

查看是否存在泄漏,然后运行{{3}}进行追踪。

希望这会有所帮助。