由于某种原因,此函数返回大多数有效图像,但对于某些函数,它只返回任何内容。它显示正在交换的数据,但图像没有正确返回。有人可以帮助我改进这个功能一些如何解决这个问题。
func imageForUrl(urlString: String, completionHandler:(image: UIImage?, url: String) -> ()) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {()in
var data: NSData? = self.cache.objectForKey(urlString) as? NSData
if let goodData = data {
let image = UIImage(data: goodData)
dispatch_async(dispatch_get_main_queue(), {() in
completionHandler(image: image, url: urlString)
})
return
}
var downloadTask: NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: urlString)!, completionHandler: {(data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
if (error != nil) {
println(error)
completionHandler(image: nil, url: urlString)
return
}
if data != nil {
println(data)
let image = UIImage(data: data)
self.cache.setObject(data, forKey: urlString)
dispatch_async(dispatch_get_main_queue(), {() in
completionHandler(image: image, url: urlString)
})
return
}
})
downloadTask.resume()
})
}
这是我正在使用的全班,它也有作者学分。
//
// ImageLoader.swift
// extension
//
// Created by Nate Lyman on 7/5/14.
// Copyright (c) 2014 NateLyman.com. All rights reserved.
//
import UIKit
import Foundation
class ImageLoader {
var cache = NSCache()
class var sharedLoader : ImageLoader {
struct Static {
static let instance : ImageLoader = ImageLoader()
}
return Static.instance
}
func imageForUrl(urlString: String, completionHandler:(image: UIImage?, url: String) -> ()) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {()in
var data: NSData? = self.cache.objectForKey(urlString) as? NSData
if let goodData = data {
let image = UIImage(data: goodData)
dispatch_async(dispatch_get_main_queue(), {() in
completionHandler(image: image, url: urlString)
})
return
}
var downloadTask: NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: urlString)!, completionHandler: {(data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
if (error != nil) {
println(error)
completionHandler(image: nil, url: urlString)
return
}
if data != nil {
println(data)
let image = UIImage(data: data)
self.cache.setObject(data, forKey: urlString)
dispatch_async(dispatch_get_main_queue(), {() in
completionHandler(image: image, url: urlString)
})
return
}
})
downloadTask.resume()
})
}
}
答案 0 :(得分:2)
您在不同主题中使用self.cache
:dispatch_async
vs dataTaskWithURL
。
不要重新发明轮子,使用经过良好测试的库来进行此类事情
下载图像并将其存储在缓存中令人惊讶的不是iOS上的简单编程任务。
此外,您可以使用同一作者的Objective-C库
UIImageView可以直接在UI控件中下载图像(并将它们存储在系统和内存缓存中)。
答案 1 :(得分:1)
为什么要努力工作。有很多方法可以用更少的代码来做同样的事情。
func downloadImage(url: NSURL, handler: ((image: UIImage, error: NSError!) -> Void)) {
var imageRequest: NSURLRequest = NSURLRequest(URL: url)
NSURLConnection.sendAsynchronousRequest(imageRequest,
queue: NSOperationQueue.mainQueue(),
completionHandler:{response, data, error in
handler(image: UIImage(data: data)!, error: error)
})
}
答案 2 :(得分:0)
我同意其他人的看法,您应该考虑使用SDWebImage或AFNetworking等完善的框架。
如果要解决此问题,则应改进错误日志记录。我还建议检查HTTP状态代码:
func imageForUrl(urlString: String, completionHandler:(image: UIImage?, url: String) -> ()) {
if let data = self.cache.objectForKey(urlString) as? NSData {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
let image = UIImage(data: data)
dispatch_async(dispatch_get_main_queue()) {
completionHandler(image: image, url: urlString)
}
}
return
}
let downloadTask = NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: urlString)!) { data, response, error in
// report basic networking errors
if data == nil {
println("\(urlString) error \(error)")
dispatch_async(dispatch_get_main_queue()) {
completionHandler(image: nil, url: urlString)
}
return
}
// report HTTP errors
if let httpResponse = response as? NSHTTPURLResponse {
let statusCode = httpResponse.statusCode
if statusCode != 200 {
println("\(urlString): statusCode = \(statusCode)")
dispatch_async(dispatch_get_main_queue()) {
completionHandler(image: nil, url: urlString)
}
return
}
}
// no HTTP error, let's try to get image
if let image = UIImage(data: data) {
self.cache.setObject(data, forKey: urlString)
dispatch_async(dispatch_get_main_queue()) {
completionHandler(image: image, url: urlString)
}
} else {
println("\(urlString) found in cache, but not valid image") // should never get here
dispatch_async(dispatch_get_main_queue()) {
completionHandler(image: nil, url: urlString)
}
}
}
downloadTask.resume()
}