【问题标题】:reloaddata() function closes tableview, and returns to be previous screenreloaddata() 函数关闭 tableview,并返回到上一个屏幕
【发布时间】:2020-02-15 14:46:02
【问题描述】:

我有一个带有两个屏幕(视图控制器和表格视图)的应用程序,每次用户更新数据上使用的过滤器时,我都会尝试在表格视图中重新加载数据。例如,我的数组保存火车时刻表数据,我根据方向过滤这些数据。用户更新方向,然后表格视图应基于重新加载并更新方向过滤器。

我尝试过使用 DispatchQueue.main.async { self.tableView.reloadData() }

我有一个按钮操作调用的函数来更新方向

@IBAction func ChangeDirection(_ sender: Any) {
    changeDirection()
}

func changeDirection()
{
    if direction == "Southbound" {
        direction = "Northbound"
    }
    else {
        direction = "Southbound"
    }

    DispatchQueue.main.async { self.tableView.reloadData() }
}

我使用带有 ui 选择器的视图控制器,因此用户可以选择他们想要火车时刻表的车站,ui 选择器访问一个单例类,该类保存每个车站的火车时刻表数据(我想知道这是否可能是问题)也许这需要从 tableview 访问。

if segue.identifier == "Stations"
    {
        let vc = segue.destination as? TableViewController
        let xmlParserSchedule = XMLParserSchedule()
        xmlParserSchedule.runScheudledParser(userStation:StationsDecoder.shared.uiStationsSorted[station])
        vc?.stationData=xmlParserSchedule.sortedArrival


    }

我希望 tableview 根据用户选择的新方向重新加载,但是 tableview 已关闭,我们返回视图控制器 ui 选择器屏幕。当我在调用 reloaddata() 时调试步入代码时,我注意到内存似乎无限泄漏。

我正在添加来自 viewcontroller 和 table view 的完整代码,以防这很有帮助:

视图控制器: 导入 UIKit

@available(iOS 9.0, *)

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    //stores picker selection for array index in station data
    var station = 0
    //UI Picker Outlet
    @IBOutlet weak var UIStationPicker: UIPickerView!



    override func viewDidLoad() {
        super.viewDidLoad()
        //self.UIStationPicker.setValue(UIColor.white, forKey: "textColor")
        self.UIStationPicker.delegate = self
        self.UIStationPicker.dataSource = self
        self.UIStationPicker.reloadAllComponents()

        //check if station file is already loaded by accessing the singletons/create plist throw method
        do {
            try? CreatePlist.shared.createPlist()
            //throw needed here to reach the catch block
            throw CreatePlist.ErrorsToThrow.fileAlreadyExists
        }catch {
            print("file already exists")
            print("time to get decoding")
            //decode the station plist using singleton class method
            StationsDecoder.shared.decoder()
            //get stations in array of dictionaries using singlton class method
            StationsDecoder.shared.getStations()
            self.UIStationPicker.reloadAllComponents()

        }
    }
    //uiPicker delegate methods
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Number of columns of data
    }
    func numberOfComponents(in pickerView: UIPickerView) ->Int {
        return 1
    }
    // The number of rows of data
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int)-> Int {
        return StationsDecoder.shared.uiStationsSorted.count
    }
    // The data to return for the row and component (column) that's being passed in
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int)-> String? {

        return StationsDecoder.shared.uiStationsSorted[row]
    }


    func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
        let titleData = StationsDecoder.shared.uiStationsSorted[row]
        let myTitle = NSAttributedString(string: titleData, attributes: [NSAttributedString.Key.font:UIFont(name: "Georgia", size: 28.0)!,NSAttributedString.Key.foregroundColor:UIColor.white])
        return myTitle
    }
    // Capture the picker view selection
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

        station = row

        performSegue(withIdentifier: "Stations", sender: Any?.self)

    }


    override func prepare(for segue: UIStoryboardSegue, sender: Any?){


    if segue.identifier == "Stations"
    {
        let vc = segue.destination as? TableViewController
        let xmlParserSchedule = XMLParserSchedule()
        xmlParserSchedule.runScheudledParser(userStation:StationsDecoder.shared.uiStationsSorted[station])
        vc?.stationData=xmlParserSchedule.sortedArrival


    }
        }



}

表格视图

import UIKit

var direction:String = "Southbound"


class TableViewController: UITableViewController{

//this code here is interesting, it dismisses the presented view with orignally presented view ie tableview is replaced with initial view controller. this avoids calling dataload method again in view controller which can duplicate your data

@IBAction func GoBack(_ sender: Any) {
        dismiss(animated: true, completion: nil)
}

@IBAction func ChangeDirection(_ sender: Any) {
    changeDirection()
}

func changeDirection()
{
    if direction == "Southbound" {
        direction = "Northbound"
    }
    else {
        direction = "Southbound"
    }

    DispatchQueue.main.async { self.tableView.reloadData() }
}

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.delegate = self
    tableView.dataSource = self

}

//array of tuples to hold station data
var stationData: [(stationfullname:String,origin: String,destination:String,lastLocation: String, dueIn: Int, late: Int, due: Int, expArrival: String, direction: String) ] = []

//array literal, for tuples
//var data = [String:(stationfullname:String,origin: String,destination:String,lastLocation: String, dueIn: Int, late: Int, due: Int, expArrival: String, direction: String)].self



override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    // As long as `total` is the last case in our TableSection enum,
    // this method will always be dynamically correct no mater how many table sections we add or remove.
      return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows

            return stationData.filter{($0.direction == direction)}.count
}

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

         return direction

}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "StationLevel", for: indexPath)
           cell.textLabel?.text = stationData.filter{($0.direction == direction)}[indexPath.row].destination
            cell.detailTextLabel?.text = "\(String(stationData.filter{($0.direction == direction)}[indexPath.row].due)) mins"

    return cell
}

}

【问题讨论】:

  • 我认为不需要 DispatchQueue.main.async { self.tableView.reloadData() } 而不是这个直接调用 reloadData() 并且只有这个代码很难识别内存泄漏
  • 感谢您的快速响应,尽管尝试 reloadData() 结果是相同的。
  • 尝试调用简单的 reloadData 让我知道它是否解决了。
  • 嗨,Pravin 这就是我上面的意思,(打字错误)的意思是说我尝试了简单的 reloadData,但它没有解决 - 得到了相同的结果
  • 是否可以将此代码放在我可以下载和调试的地方。

标签: ios swift


【解决方案1】:

哦,Lordie,原来我有一个额外的已发送事件,用于发送回视图控制器的按钮,有 4 个小时我永远不会回来。 感谢 Parvin 的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-22
    • 1970-01-01
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    相关资源
    最近更新 更多