【问题标题】:NSURLSession return dataNSURLSession 返回数据
【发布时间】:2015-10-28 22:35:17
【问题描述】:

我有问题。我想从 Internet 下载图像,并在下载时显示“指示器”。问题是当没有互联网连接时,方法“downloadedFrom”进入“if error!= nil”,因此“指示器”永远不会中断。这是我的代码。

var imageArray:[String]! = ["http://findicons.com/files/icons/1072/face_avatars/300/a01.png", "http://findicons.com/files/icons/1072/face_avatars/300/a02.png", "http://findicons.com/files/icons/1072/face_avatars/300/a03.png", "http://findicons.com/files/icons/1072/face_avatars/300/a04.png", "http://findicons.com/files/icons/1072/face_avatars/300/a05.png"]   

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let newCell = tableView.dequeueReusableCellWithIdentifier("userCell") as! UserCell_TableViewCell
        let selectedUser = userArray[indexPath.row]

        newCell.userDescription?.text = selectedUser.getFirstName() + " " + selectedUser.getLastName()
            let randomNumber = arc4random_uniform(4)
            let arrayIndex = Int(randomNumber)
            let urlImage = imageArray[arrayIndex]

            newCell.loadIndicator.startAnimating()

            downloadedFrom(urlImage) { userImage in
                dispatch_async(dispatch_get_main_queue()){
                    newCell.userImage.image = userImage
                    newCell.loadIndicator.stopAnimating()
                }

                self.userArray[indexPath.row].setImage(userImage)
            }

        return newCell
    }

    func downloadedFrom(urlLink :String, completionHandler: (UIImage) -> ())
    {
        if let urlData = NSURL(string: urlLink) {
            NSURLSession.sharedSession().dataTaskWithURL(urlData) { (data, response, error) in
                if error != nil {
                    print("error=\(error)")
                    return
                } else {
                    if let httpResponse = response as? NSHTTPURLResponse {
                        let userImage = httpResponse.statusCode == 200 ? UIImage(data: data!) : UIImage(named: "unknownImage")

                        completionHandler(userImage!)
                    }}
                }.resume()
        }
    }

编辑

    import UIKit

    class UserCell_TableViewCell: UITableViewCell {

    @IBOutlet weak var userImage: UIImageView!
    @IBOutlet weak var userDescription: UILabel!
    @IBOutlet weak var loadIndicator: UIActivityIndicatorView!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

    func downloadedFrom(urlLink :String)
    {

        self.loadIndicator.startAnimating()

        if let urlData = NSURL(string: urlLink) {

            NSURLSession.sharedSession().dataTaskWithURL(urlData) { (data, response, error) in

                if error != nil {

                    print("error = \(error)")

                    self.loadIndicator.stopAnimating()

                    return

                } else {

                    // El servidor contesta la petición, pero la imágen puede no existir.
                    if let httpResponse = response as? NSHTTPURLResponse {

                        if httpResponse.statusCode == 200 {

                            dispatch_async(dispatch_get_main_queue()){

                                self.userImage.image = UIImage(data: data!)

                                self.loadIndicator.stopAnimating()

                            }}
                    }}

                }.resume()
        }

    }

}

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let newCell = tableView.dequeueReusableCellWithIdentifier("userCell") as! UserCell_TableViewCell
        let selectedUser = userArray[indexPath.row]

        newCell.userDescription?.text = selectedUser.getFirstName() + " " + selectedUser.getLastName()

            let randomNumber = arc4random_uniform(4)

            let arrayIndex = Int(randomNumber)

            let urlImage = imageArray[arrayIndex]

            newCell.downloadedFrom(urlImage)

        return newCell
    }

导致我这样做的问题是,我需要您下载图像以将其保存到数组中,方法 cellForRowAtIndexPath 中的数组完整性

【问题讨论】:

    标签: ios swift nsurlsession


    【解决方案1】:

    首先我想提一下,尝试在表格单元格方法中调度加载循环(即使在单独的线程中)是不好的做法。您正在执行的块将捕获newCell 指针,因此如果在将单元格从表格中移出并重新使用后加载图像,则图像将被加载到错误的表格单元格中。

    解决问题的最佳方法是将加载函数移动到单元格的类本身中。所以在配置单元格时,只需提供单元格的链接,让单元格处理图片加载即可。

    为了解决最初的问题,您可以修改加载过程,以便在单元格从表格中移出时(也就是调用prepareForReuse())取消加载过程。

    在单元格的类中,您可以添加对互联网连接的检查,以便在返回错误时停止指示器。当您将功能移动到单元格的类时,这将变得更加清晰。

    【讨论】:

    • 感谢您的帮助。我是新来的。你能帮我多一点吗?我编辑帖子,看看我是否理解他所说的。
    • 这看起来基本正确!您只需要解决当单元格移出屏幕时会发生什么的问题。因此,当这种情况发生时,单元格被标记为重复使用,因此您希望停止加载图像(除非您不重复使用单元格)。这可以通过添加BOOL 标志来实现,并在单元格不应加载图像时将其设置为false(在prepareForReuse() 中)。当图像在您的下载的From() 中加载时,您需要检查此标志以查看您是否真的应该加载图像。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-30
    • 2016-06-13
    • 1970-01-01
    • 2016-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多