向下滚动时出现致命错误

时间:2017-08-30 06:08:36

标签: ios json swift

我在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()
    }

}

enter image description here

3 个答案:

答案 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()
        }