我在tableView中传递json,但是当我向下滚动几次时,它显示消息“致命错误:在展开可选值时意外发现nil”
let imageCache = NSCache<AnyObject, AnyObject>()
class CustomImageView: UIImageView {
var imageUrlString: String?
func loadImageUsingUrlString(_ urlString: String) {
imageUrlString = urlString
let urlEncoded = urlString.addingPercentEncoding( withAllowedCharacters: .urlQueryAllowed)
let url = URL(string: urlEncoded!)
image = nil
if let imageFromCache = imageCache.object(forKey: urlString as AnyObject) as? UIImage {
self.image = imageFromCache
return
}
// crush here down line
URLSession.shared.dataTask(with: url!, completionHandler: {(myData, respones, error) in
if error != nil {
print(error ?? 0)
return
}
DispatchQueue.main.async(execute: {
let imageToCache = UIImage(data: myData!)
if self.imageUrlString == urlString {
self.image = imageToCache
}
imageCache.setObject(imageToCache!, forKey: urlString as AnyObject)
})
}).resume()
}
}
答案 0 :(得分:1)
将URLSession.shared.dataTask(with:completionHandler:)
包含在if-let
这样的句子中:
if let url = url {
URLSession.shared.dataTask(with: url, completionHandler: {(myData, respones, error) in
if error != nil {
print(error ?? 0)
return
}
DispatchQueue.main.async(execute: {
let imageToCache = UIImage(data: myData!)
if self.imageUrlString == urlString {
self.image = imageToCache
}
imageCache.setObject(imageToCache!, forKey: urlString as AnyObject)
})
}).resume()
}
注意:并且尽量不要使用force-unwrapping
(!
)。而是尽可能在optional binding
处使用if-let
。
由于您可能是optional
的新用户,我发布了可能的崩溃处理代码。虽然我没有改变逻辑,但我修复了可能的崩溃相关代码:
let imageCache = NSCache<AnyObject, AnyObject>()
class CustomImageView: UIImageView {
var imageUrlString: String?
func loadImageUsingUrlString(_ urlString: String) {
imageUrlString = urlString
guard let urlEncoded = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {
print("Encoding not done")
return
}
let url = URL(string: urlEncoded)
image = nil
if let imageFromCache = imageCache.object(forKey: urlString as AnyObject) as? UIImage {
self.image = imageFromCache
return
}
if let url = url {
URLSession.shared.dataTask(with: url, completionHandler: {(myData, respones, error) in
if error != nil {
print(error ?? 0)
return
}
if let myData = myData {
DispatchQueue.main.async(execute: {
let imageToCache = UIImage(data: myData)
if self.imageUrlString == urlString {
self.image = imageToCache
}
if let imageToCache = imageToCache {
imageCache.setObject(imageToCache, forKey: urlString as AnyObject)
}
})
}
}).resume()
}
}
}
答案 1 :(得分:0)
您需要在使用前检查网址
为此你可以使用这两个选项
1)if let
2)guard let
(更好)
即
此处替换此代码
let url = URL(string: urlEncoded!)
带
guard let url = URL(string: urlEncoded) else {
print("Your Url is nil")
return
}
在你强行取消扭曲之前,你必须确定值,否则如果let或guard阻止
此处也使用guard let
guard let imageFromCache = imageCache.object(forKey: urlString as AnyObject) as? UIImage else {
return
}
它使您的代码易于阅读
希望对你有所帮助
答案 2 :(得分:0)
可能是网址为零,请尝试使用此代码。
if url.absoluteString != "" {
URLSession.shared.dataTask(with: url, completionHandler: {(myData, respones, error) in
if error != nil {
print(error ?? 0)
return
}
DispatchQueue.main.async(execute: {
let imageToCache = UIImage(data: myData!)
if self.imageUrlString == urlString {
self.image = imageToCache
}
imageCache.setObject(imageToCache!, forKey: urlString as AnyObject)
})
}).resume()
}