【问题标题】:Getting Image from URL Objective C从 URL Objective C 获取图像
【发布时间】:2010-10-30 07:20:13
【问题描述】:

我正在尝试从 URL 获取图像,但它似乎不适合我。有人能指出我正确的方向吗?

这是我的代码:

NSURL *url = [NSURL URLWithString:@"http://myurl/mypic.jpg"];

NSString *newIMAGE = [[NSString alloc] initWithContentsOfURL:url
                                       encoding:NSUTF8StringEncoding error:nil];

cell.image = [UIImage imageNamed:newIMAGE];

当我调试 newIMAGE 字符串为 nil 时,有些东西在那里不起作用。

【问题讨论】:

    标签: objective-c


    【解决方案1】:

    您想要的是获取图像数据,然后使用该数据初始化 UIImage:

    NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: @"http://myurl/mypic.jpg"]];
    cell.image = [UIImage imageWithData: imageData];
    [imageData release];
    

    根据要求,这是一个异步版本:

    dispatch_async(dispatch_get_global_queue(0,0), ^{
        NSData * data = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: @"http://myurl/mypic.jpg"]];
        if ( data == nil )
            return;
        dispatch_async(dispatch_get_main_queue(), ^{
            // WARNING: is the cell still using the same data by this point??
            cell.image = [UIImage imageWithData: data];
        });
        [data release];
    });
    

    【讨论】:

    • 这是同步的,能不能加个代码在后台下载,因为它阻塞了ui线程
    • 几个问题: 1. 你有一个关于确保单元格仍然可见的评论。您可以使用UITableViewCell *updateCell = [tableView cellForRowAtIndexPath:indexPath]; 后跟if (updateCell) ... 来执行此操作(显然,使用这个updateCell 而不是原来的cell 来更新imageView;2. 如果异步执行,请确保初始化@ 987654329@ 属性为您的imageView 在您启动异步检索过程之前; 3. 你真的应该做缓存,所以它不必每次滚动回以前加载的图像时重新检索它。
    • Rob 在 -> stackoverflow.com/questions/16663618/… 发布了上面第 1 点和第 2 点的清晰代码示例(谢谢 Rob)
    【解决方案2】:

    好吧,这里有几个问题:

    1. 从URL(url)到NSString(newImage)的转换不正确,代码实际上是尝试将“http://myurl/mypic.jpg”的内容加载到NSString中。

    2. -imageNamed 方法采用一个字符串作为参数,该字符串是本地文件的路径,而不是 URL。

    您需要使用 NSData 对象作为中介,如下例所示: http://blogs.oreilly.com/digitalmedia/2008/02/creating-an-uiimage-from-a-url.html

    【讨论】:

      【解决方案3】:

      接受的答案异步版本在我的代码中运行得很慢。使用 NSOperation 的方法运行速度快了光年。 Joe Masilotti 提供的代码 --> objective - C : Loading image from URL?(并粘贴在下面):

      -(void) someMethod {
          // set placeholder image
          UIImage* memberPhoto = [UIImage imageNamed:@"place_holder_image.png"];
      
          // retrieve image for cell in using NSOperation
          NSURL *url = [NSURL URLWithString:group.photo_link[indexPath.row]];
          [self loadImage:url];
      }
      
      - (void)loadImage:(NSURL *)imageURL
      {
          NSOperationQueue *queue = [NSOperationQueue new];
          NSInvocationOperation *operation = [[NSInvocationOperation alloc]
                                              initWithTarget:self
                                              selector:@selector(requestRemoteImage:)
                                              object:imageURL];
          [queue addOperation:operation];
      }
      
      - (void)requestRemoteImage:(NSURL *)imageURL
      {
          NSData *imageData = [[NSData alloc] initWithContentsOfURL:imageURL];
          UIImage *image = [[UIImage alloc] initWithData:imageData];
      
          [self performSelectorOnMainThread:@selector(placeImageInUI:) withObject:image waitUntilDone:YES];
      }
      
      - (void)placeImageInUI:(UIImage *)image
      {
          [self.memberPhotoImage setImage:image];
      }
      

      【讨论】:

        【解决方案4】:

        Swift 3 和 4

        let theURL = URL(string:"https://exampleURL.com")
        let imagedData = NSData(contentsOf: theURL!)!
        let theImage = UIImage(data: imagedData as Data)
        cell.theImageView.image = theImage
        

        这将在主线程中完成。

        并在异步/后台线程

        中执行相同的操作
           DispatchQueue.main.async(){
              let theURL = URL(string:"https://exampleURL.com")
              let imagedData = NSData(contentsOf: theURL!)!
              let theImage = UIImage(data: imagedData as Data)
           }
           cell.theImageView.image = theImage
        

        【讨论】:

          【解决方案5】:

          不再需要更新 Jim dovey 的答案,[data release],因为在更新的苹果指南中。内存管理由ARC(自动计数引用)自动完成,

          这是更新后的asynchronous call

          dispatch_async(dispatch_get_global_queue(0,0), ^{
                  NSData * data = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: @"your_URL"]];
                  if ( data == nil )
                      return;
                  dispatch_async(dispatch_get_main_queue(), ^{
                      self.your_UIimage.image = [UIImage imageWithData: data];
                  });
          
              });
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-05-01
            • 1970-01-01
            • 2015-01-29
            • 1970-01-01
            • 2021-12-31
            • 2017-11-16
            相关资源
            最近更新 更多