【问题标题】:Swift UIRefresh Control Drag to refresh in UITableView causes app crashSwift UIRefresh Control 在 UITableView 中拖动刷新会导致应用崩溃
【发布时间】:2020-02-18 08:21:52
【问题描述】:

我的 TableView 中有一个 UIRefreshControll。一切正常,但如果我拉得太快,应用程序就会崩溃。 错误:致命错误:索引超出范围

当我从按钮调用函数 refreshData 时,不会出现崩溃。有点奇怪,因为 refreshControll 没有做与调用动作不同的事情。 我希望有人可以帮助我。

private let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(self.refreshData), for: .valueChanged)

if #available(iOS 10.0, *) {
                    self.tableView.refreshControl = self.refreshControl
                } else {
                    self.tableView.addSubview(self.refreshControl)
                }

@objc private func refreshData() {

    if isRefreshing {
        self.refreshControl.endRefreshing()
        return
    }
    isRefreshing = true
    print("refresh")

    guard let url = URL(string: taskURL) else {
        return
    }

    let request = URLRequest(url: url)

    urlSessionBackground.dataTask(with: request) { (dataOpt, response, error) in

        if error != nil {
            DispatchQueue.main.async {
                let alert = UIAlertController(title: "Loading Error", message: "No Internet Connection. Please try again later.", preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: {(action: UIAlertAction!) in
                    self.refreshControl.endRefreshing()
                }))
                self.present(alert, animated: true)
            }
            return
        }else {
            self.data.removeAll()
            self.userImage.removeAll()
            self.currentData.removeAll()
            self.taskDetails.removeAll()
        }

        guard let dataNew = dataOpt else {
            return
        }

        let appdata = try? JSONDecoder().decode(TaskList.self, from: dataNew)

        for data in appdata!{

              self.data.append(CellData.init(image: UIImage(named: "Profile"), message: data.name, checkImage: data.status))
                self.userImage.append("")

              self.taskDetails.append(TaskDetails.init(status: data.status, assigned: data.assigneUid, time: data.duedateTsUTC, priority: data.priority, desc: data.desc, uid: data.uid))


        }

        self.currentData = self.data

        DispatchQueue.main.async {
            self.tableView.reloadData()
            self.searchBar.text = ""
            self.isRefreshing = false
            self.refreshControl.endRefreshing()
        }

    }.resume()
}

修复它:使用临时变量来保存数据并在之后使用。删除数据是个问题。

【问题讨论】:

  • 你试过调试它吗?崩溃到底在哪里?
  • @Simon Liebers 如果 isRefreshing { self.refreshControl.endRefreshing() //在此处清空您的表数据 return },您可以尝试清空本节中的表数据吗
  • @Lu_ 在函数 cellForRowAt indexPath 上。所以在重新加载 TableView
  • @dakrawat 在我的情况下不起作用。
  • 如果你在 cellForRowAt indexPath 上崩溃了,那么它很有可能是由于 array.so 我的建议是在每次调用它时检查数组数据的内容,因为如果 arraydata 之前被更改并以某种方式被删除tableviewReloading 的中间然后它会崩溃你也可以像我之前所说的那样删除所有数组数据,然后重新加载 tableview adata

标签: ios swift web-services refresh


【解决方案1】:

试试这个

    if error != nil {
        DispatchQueue.main.async {
            let alert = UIAlertController(title: "Loading Error", message: "No Internet Connection. Please try again later.", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: {(action: UIAlertAction!) in
                self.refreshControl.endRefreshing()
            }))
            self.present(alert, animated: true)
        }
        return
    }else {
        if self.data != nil{            
           self.data.removeAll()
        }
        if self.userImage != nil{            
           self.userImage.removeAll()
        }
        if self.currentData != nil{            
           self.currentData.removeAll()
        }
        if self.taskDetails != nil{            
           self.taskDetails.removeAll()
        }
    }

【讨论】:

    【解决方案2】:

    试试这个

    var dataTask: URLSessionDataTask?
    let defaultSession = URLSession(configuration: .background)
    
    @objc private func refreshData() {
    
    if isRefreshing {
        self.refreshControl.endRefreshing()
        return
    }
    isRefreshing = true
    print("refresh")
    guard let url = URL(string: taskURL) else {
        return
    }
    dataTask?.cancel()
    let request = URLRequest(url: url)
    
    dataTask = 
    defaultSession.dataTask(with: url) { [weak self](dataOpt, response, error) in 
    defer {
      self?.dataTask = nil
    }
    
    if let error = error {
      DispatchQueue.main.async {
                let alert = UIAlertController(title: "Loading Error", message: "No Internet Connection. Please try again later.", preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: {(action: UIAlertAction!) in
                    self.refreshControl.endRefreshing()
                }))
                self.present(alert, animated: true)
            }
            return
    
    } else if 
      let data = dataOpt,
      let response = response as? HTTPURLResponse,
      response.statusCode == 200 {  
            self.data.removeAll()
            self.userImage.removeAll()
            self.currentData.removeAll()
            self.taskDetails.removeAll()      
        let appdata = try? JSONDecoder().decode(TaskList.self, from: data)
    
        for data in appdata!{
    
              self.data.append(CellData.init(image: UIImage(named: "Profile"), message: data.name, checkImage: data.status))
                self.userImage.append("")
    
              self.taskDetails.append(TaskDetails.init(status: data.status, assigned: data.assigneUid, time: data.duedateTsUTC, priority: data.priority, desc: data.desc, uid: data.uid))
    
    
        }
    
        self.currentData = self.data
    
        DispatchQueue.main.async {
            self.tableView.reloadData()
            self.searchBar.text = ""
            self.isRefreshing = false
            self.refreshControl.endRefreshing()
        }
    }
    }
    
    
    dataTask?.resume()
    
    }
    

    【讨论】:

    • 这个 if 块只是为了避免一次又一次地刷新。我不想在那里停止该方法。而且它不起作用。
    猜你喜欢
    • 2018-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 1970-01-01
    • 1970-01-01
    • 2012-06-28
    相关资源
    最近更新 更多