图像不会异步加载以在swift项目中填充ImageView

时间:2015-04-09 17:09:09

标签: swift xml-parsing

我在迅速发展方面相当新。我的第一个项目几乎完成,除了我无法异步下载图像。当我编译我的项目时,我没有看到我设置的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)

我项目中的一个单元格:

i.imgur.com/9WojOuA.png

2 个答案:

答案 0 :(得分:0)

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

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

最重要的是,确保调用此函数,就像您认为的那样,并确保其使用的URL看起来正确。如果图像检索失败,您可能还应该记录一些消息,因此您知道它失败了。理想情况下,您应该使用类似NSURLSession.sharedSession().dataTaskForURL(url, completionHandler:...)的内容,因为它提供了一个NSError对象,可用于诊断问题。现在你正在盲目飞行。

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

enter image description here

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

执行此操作后,您将获得有关视图的长文本说明,并检查frame以查看相关图片视图。

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

enter image description here


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

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

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

    下划线,如果单元格滚出屏幕,您可能想要取消旧请求。

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

    < / LI>
  • 如果您要对图像进行缓存,那么您应该didReceiveMemoryWarning清空该缓存。如果你要进行缓存,你可能想要将它们都缓存到持久存储和内存中,这样如果你必须在内存压力下清除内存,你仍然在本地持久存储中有一个副本,而不是必须检索整个图像。

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

答案 1 :(得分:0)

谢谢大家,我的问题是与AFNetworking合作