我在迅速发展方面相当新。我的第一个项目几乎完成,除了我无法异步下载图像。当我编译我的项目时,我没有看到我设置的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)
我项目中的一个单元格:
答案 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
对象,可用于诊断问题。现在你正在盲目飞行。
最后,你说你看不到你的图像视图。它是否有可能存在,而是存在不正确的约束使其无法看到?我会运行应用程序,点击暂停按钮:
然后,在(lldb)
提示符下,输入po [[UIWindow keyWindow] recursiveDescription]
。
执行此操作后,您将获得有关视图的长文本说明,并检查frame
以查看相关图片视图。
顺便说一句,您还可以使用视图调试器确认图像视图的位置(尽管有时很难识别不可见的,即零宽度的视图):
话虽如此,这里有很多更深层次的问题:
细胞被重复使用。因此,在异步图像检索请求时,您无法确信您引用的imageView
仍然用于启动请求时所在的同一行。 (在异步方法返回时,它可能用于表/集合视图中完全不同的行。)而不是将此例程传递给UIImageView
引用,而应该传递它可以使用的信息。以后用于(a)在表中找到适当的行(如果在我们发出请求的时间和检索图像之间插入/删除了其他行); (b)查看该行的单元格是否仍然可见; (c)只有在找到合适的可见单元格时才更新该图像视图。
您确实需要这是一个可取消的请求。如果用户快速从表格中的第一行滚动到第100行,则不希望它在检索当时可见行的图像之前必须检索前99个图像。否则,在网络连接速度较慢的情况下,图像检索之前可能需要一分钟左右(当用户坐在那里,站在无图像视图时,这是永恒的。)
下划线,如果单元格滚出屏幕,您可能想要取消旧请求。
每次调用时,asyncLoadShotImage
都会创建一个新队列。这意味着您不会限制应用程序将创建多少个线程。如果要多次调用此函数,您可能希望使用单个队列(我倾向于使用操作队列,一个是并发的,但会限制并发度)。
如果您要对图像进行缓存,那么您应该didReceiveMemoryWarning
清空该缓存。如果你要进行缓存,你可能想要将它们都缓存到持久存储和内存中,这样如果你必须在内存压力下清除内存,你仍然在本地持久存储中有一个副本,而不是必须检索整个图像。
最重要的是,要做到这一点并非易事。您可能需要考虑使用其中一个UIImageView
类别(例如SDWebImage或AFNetworking中包含的类别)。它会让你的生活更轻松。
答案 1 :(得分:0)
谢谢大家,我的问题是与AFNetworking合作