【问题标题】:Images wont load asynchronously to fill UIImageView on swift project图像不会异步加载以填充 swift 项目上的 UIImageView
【发布时间】:2015-04-09 17:09:09
【问题描述】:

我在快速开发方面相当陌生。我的第一个项目几乎完成了,除了我无法异步下载图像。当我编译我的项目时,我没有看到我设置的 UIImage 占位符,所以我不完全确定发生了什么。我确信我的问题具有约束力。任何帮助将不胜感激

// Async Code

func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: [NSObject : AnyObject]!) {
    eName = elementName
    if elementName == "item" {
        postTitle = String()
        postLink = String()
    }
}

func parser(parser: NSXMLParser!, foundCharacters string: String!) {
    let data = string.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    if (!data.isEmpty) {
        if eName == "title" {
            postTitle += data
        } else if eName == "link" {
            postLink += data
        }
    }
}

func parser(parser: NSXMLParser!, didEndElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!) {
    if elementName == "item" {
        let blogPost: BlogPost = BlogPost()
        blogPost.postTitle = postTitle
        blogPost.postLink = postLink
       //blogPost.postImage = postImage
        blogPosts.append(blogPost)
    }
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return blogPosts.count
}

// Image View
func asyncLoadShotImage(imageView : UIImageView) {

    let downloadQueue = dispatch_queue_create("com.iShots.processdownload", nil)

    dispatch_async(downloadQueue) {

        var data = NSData(contentsOfURL: NSURL(string: self.imageUrl)!)

        var image : UIImage?
        if data != nil {
           self.imageData = data!
            image = UIImage(data: data!)!
        }

        dispatch_async(dispatch_get_main_queue()) {
            imageView.image = image
        }
    }


}

这是这样称呼的:

asyncLoadShotImage(cell.myImageLabel)

我项目中的一个单元格:

【问题讨论】:

  • 我认为所有NSXMLParser 代码都与您手头的问题无关?如果是这样,也许你应该删除它。同样,didReceiveMemoryWarning 似乎不相关。但是,您没有向我们展示的是您调用asyncLoadShotImage 的位置(我假设您在cellForRowAtIndexPath 或类似的地方进行此操作)。

标签: swift xml-parsing


【解决方案1】:

asyncLoadShotImage 正在从self.imageUrl 的内容中加载NSData。后来它引用了self.imageData。令人担忧的是,您有引用self 的单元格图像检索逻辑(我认为它是表格视图控制器)。如果您有十几个单元格异步检索图像,那么imageUrl 那么引用哪个 URL?我希望看到引用一组图像 URL 的代码,而不仅仅是一个。 imageData 用于哪个单元格?我希望看到一个 NSCache 的图像数据对象,而不仅仅是一个 NSData

如果您没有看到您的图像被填充,那么您应该让asyncLoadShotImage 记录它试图从中检索图像的 URL,并确保它没问题。另外,我从imageData 引用中推断您正在尝试对图像进行一些缓存,但是您没有向我们展示您何时检索此asyncLoadShotImage 的逻辑,但那里可能存在错误,也是。

最重要的是,确保调用此函数的方式符合您的预期,并确保它使用的 URL 看起来正确。如果图像检索失败,您可能还应该记录一些消息,这样您就知道它失败了。理想情况下,您应该使用NSURLSession.sharedSession().dataTaskForURL(url, completionHandler:...) 之类的东西,因为它提供了一个NSError 对象,您可以使用它来诊断问题。现在你瞎了眼。

最后,你说你看不到你的图像视图。它是否可能存在,而是存在不正确的约束使其无法看到?我会运行应用程序,点击暂停按钮:

然后,在(lldb) 提示符下,输入po [[UIWindow keyWindow] recursiveDescription]

执行此操作时,您将获得视图的长文本描述,并检查 frame 以获取相关图像视图。

顺便说一句,您还可以使用视图调试器确认图像视图的位置(尽管有时很难识别不可见的视图,即零宽度视图):


话虽如此,这里还有很多更深层次的问题:

  • 细胞被重复使用。因此,您无法确信在异步图像检索请求时,您引用的 imageView 仍用于您启动请求时的同一行。 (在异步方法返回时,它可能用于表/集合视图中完全不同的行。)与其向该例程传递UIImageView 引用,不如向它传递它可以在以后使用的信息用于 (a) 在表中找到适当的行(以防在我们发出请求和检索图像之间插入/删除其他行); (b) 查看该行的单元格是否仍然可见; (c) 仅当我们找到合适的可见单元格时才更新该图像视图。

  • 您确实需要这是一个可取消的请求。如果用户从第一行快速滚动到表中的第 100 行,您不希望它必须先检索前 99 个图像,然后再检索随后可见行的图像。否则,在网络连接速度较慢的情况下,很容易在图像检索前一分钟左右(当用户坐在那里,站在无图像视图时,这是一个永恒的时间)。

    底线,如果单元格滚动到屏幕外,您可能想取消旧请求。

  • 您的asyncLoadShotImage 在您每次调用它时都会创建一个新队列。这意味着您不会限制应用程序将创建多少线程。如果要多次调用此函数,您可能希望使用单个队列(我更倾向于使用操作队列,它是并发的,但会限制并发程度)。

  • 如果你要缓存图像,你真的应该让didReceiveMemoryWarning清空缓存。如果您要进行缓存,您可能希望同时缓存到持久存储和内存,这样如果您必须在内存压力下清除内存,您仍然可以在本地持久存储中保存一份副本,而不必检索整个图像。

最重要的是,正确地做到这一点并非易事。您可能需要考虑使用其中一种UIImageView 类别(例如包含在 SDWebImage 或 AFNetworking 中的类别)。它会让你的生活更轻松。

【讨论】:

    【解决方案2】:

    谢谢大家,我在使用 AFNetworking 时遇到了问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-11
      • 2015-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-16
      • 1970-01-01
      相关资源
      最近更新 更多