【问题标题】:How to retrieve images from server asynchronously如何从服务器异步检索图像
【发布时间】:2013-04-27 11:15:27
【问题描述】:

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

【问题讨论】:

    标签: objective-c


    【解决方案1】:

    您可以使用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];
    

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

    【讨论】:

      【解决方案2】:

      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
            });
       });
      

      【讨论】:

      • 当我使用这个代码时,我在 UIImage *image=[UIImage imageWithData:data] @Prine 得到错误“Expected expression”
      【解决方案3】:

      您可以使用 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

      【讨论】:

      • 谢谢 x4h1d,我可以把这段代码放在哪里,我混淆了 AsycImageView 类或我的类
      • @Raven,无论你在哪里写 NSData *imageData = [NSData dataWithContentsOfURL:your_image_URL]; UIImage *img = [UIImage imageWithData:imageData];改写上面的代码。
      • @Raven,如果答案有效并且您觉得它有用,请接受并投票。谢谢。
      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

        如果您真的想异步下载图像,我建议您使用来自AFNetworkingUIImageView category,它已经过全面测试并且维护得很好。

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

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

        查看是否存在泄漏,然后运行Leaks Instrument 进行追踪。

        希望这会有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-09-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-09
          • 2015-11-17
          • 2012-11-25
          相关资源
          最近更新 更多