我有一个带有两个屏幕的应用程序(视图控制器和表视图),每次用户更新对数据使用的过滤器时,我都试图在表视图中重新加载数据。例如,我的数组保存火车时刻表数据,我根据方向过滤此数据。用户更新方向,然后tableview应该基于重新加载并更新方向过滤器。
我尝试使用 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
}
我希望表格视图根据用户选择的新方向重新加载,但是表格视图已关闭,我们返回到视图控制器ui选择器屏幕。当我在调用reloaddata()时调试代码时,我注意到内存似乎无限地泄漏。
如果有帮助,我正在从ViewController和表视图中添加完整的代码:
视图控制器: 导入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
}
}
}
tableview
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
}
}
答案 0 :(得分:0)
哦,Lordie,原来我有一个额外的已发送事件,该事件是发送回视图控制器的按钮,有4个小时我再也回不来了。 感谢您的帮助,不管Parvin。