简体   繁体   English

Swift:如何处理表视图与方法更新表视图之间的同步

[英]Swift: How to handle synchronisation between table view and method updating table view

I have an array in swift which is constantly being updated by another method and it also needs to be loaded to table view after update. 我有一个数组,它正在迅速地被另一种方法不断更新,并且更新后还需要将其加载到表视图中。 The method updating the array is called frequently. 经常调用更新数组的方法。 I am having threading issue. 我遇到穿线问题。 I tried using a lock on array when the updating method is called. 调用更新方法时,我尝试在数组上使用锁。 It did improve but but it is not working quite well as well. 它确实有所改进,但效果也不佳。 I am getting fatal error: Index out of range when it is updating the table in case of large number of elements (around >50) in array. 我收到fatal error: Index out of range如果数组中有大量元素(大约> 50),则更新表时fatal error: Index out of range

What would be the best approach to handle this situation and make it thread-safe. 什么是处理这种情况并使其成为线程安全的最佳方法? I am new to Swift. 我是Swift的新手。

Below is the function to update myArray: 下面是更新myArray的函数:

func updateMyArray() {
       objc_sync_enter(self.myArray)
                //do some stuff with my Array
        //…………add some elements in array………
        //…………remove some elements in array……
                DispatchQueue.main.async {
                    self.myTable.reloadData()
                    }
       objc_sync_exit(self.myArray)

    }

Below is the table delegate methods: 下面是表委托方法:

func numberOfRows(in tableView: NSTableView) -> Int {
      return myArray.count
}

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        var cellText: String = myArray[row]
        if let cell = myTable.make(withIdentifier:  “myCellIdentifier", owner: nil) as? NSTableCellView {
            cell.textField?.stringValue = cellText
            return cell
        }
}

updateMyArray() is called every 10 seconds 每10秒调用一次updateMyArray()

override func viewDidAppear() {
        _ = Timer.scheduledTimer(timeInterval: 10.0, target: self, selector: #selector(self.updateMyArray), userInfo: nil, repeats: true)
     }

updateMyArray() is called by pushing refresh button 通过按下刷新按钮来调用updateMyArray()

@IBAction func refreshMyArray(_ sender:NSButton){
     self.updateMyArray()
}

When declaring your array add this: 在声明数组时,添加以下内容:

var myArray=[type]() {
   didSet{
       DispatchQueue.main.async {
          self.myTable.reloadData()
        }
    }
}

So whenever your array is updated the tableView is reloaded with proper data. 因此,无论何时更新数组,tableView都会重新加载适当的数据。

This is what worked for me: 这对我有用:

In updateMyArray() method: 在updateMyArray()方法中:

func updateMyArray() {
        self.updatingTableData = true
        //do some stuff with my Array
        //…………add some elements in array………
        //…………remove some elements in array……     
       self.updatingTableData = false
        //following can also be done in didSet part of myArray variable
       DispatchQueue.main.async {
             self.myTable.reloadData()
       }

    }

In table view delegate method: 在表视图委托方法中:

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        if self.updatingTableData == true || row >= self.printers.count {
                 return nil
        }
        var cellText: String = myArray[row]
        if let cell = myTable.make(withIdentifier:  “myCellIdentifier", owner: nil) as? NSTableCellView {
            cell.textField?.stringValue = cellText
            return cell
        }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM