从其他线程通知UITable

时间:2017-11-16 10:41:11

标签: ios arrays swift uitableview data-binding

我有一个简单的UITable实现和一个名为fruits的数组。摘自this示例。唯一的区别是我正在使用UIViewController作为UITable的一个UITableViewController,但现在这应该是无关紧要的。

class MainViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var fruits : [String] = Array() 
    let thread : GetDataForFruitsArrayThread

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return fruits.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "LabelCell", for: indexPath)

        cell.textLabel?.text = fruits[indexPath.row]

        return cell
    }

    }

现在我在这个类中也有一个viewDidLoad函数。在函数中我调用一个线程,它将数组作为参数。该线程以异步方式使用新值填充数组。意味着我不知道是否会有任何值,或者何时显示值并将其设置到数组中。所以你可以想象我在这一点上要问的问题:一旦视图将数组加载到UITable中,我如何通知UITableView我已经改变了数组的内容。在c#中有NotifyAll()函数,该函数不支持属性的所有侦听器。有没有一种简单而高效的方法可以在swift中执行此操作,可选择不导入任何未包含的库?

override func viewDidLoad() {
    super.viewDidLoad()
    self.thread = GetDataForFruitsArrayThread(array: &fruits)
    self.thread.StartAsynchronously() 

}

编辑 - 添加GetDataForFruitsArrayThread

 class GetDataForFruitsArrayThread : MyThread {

 var array : [String]

 init(array: inout [String] ) {
   self.array = array
 }


 override func main() {

      // init socket

 while(true){

      _ = withUnsafeMutablePointer(to: &rcvaddr){
            $0.withMemoryRebound(to: sockaddr.self, capacity: 1){
      recvfrom(m_socket, &pData, bufferlength, 0, UnsafeMutablePointer($0), 
               &socketAddressLength)
            }
        }

        var fruit = String(cString:inet_ntoa(rcvaddr.sin_addr), encoding: .ascii)
        self.array.append(fruit)

   }
 }
}

编辑 - 21.11.2017:

根据Sandeep Bhandari的回答,我在ViewController中更改了以下代码:

@IBOutlet weak var tableView1: UITableView!

var fruits : [String] = Array() {
        didSet {
            self.tableView1.reloadData()
        }
    }

问题:我在GetDataForFruitsArrayThread-class中的array.append(fruit)设置断点。之后,didSet方法中有一个断点。但是这个断点在append()之后没有调用 - 调用!注意:GetDataForFruitsArrayThread-class的init函数上的参数是一个in-out参数!

更新:我发现如果我在GetDataForFruitsArrayThread线程中的GetDataForFruitsArrayThread.array上执行array.append(fruit)-call,则ViewController类中的Fruits-array不会被更改,因此didSet没有得到调用。我该如何改变这种行为?

1 个答案:

答案 0 :(得分:2)

因为您说您正在运行一个无休止的过程来继续更新阵列,并且您希望在阵列更改后更新UI,您可以使用以下解决方案。

var fruits : [String] = Array() {
        didSet {
            self.tableView.reloadData()
        }
    }

我在做什么? Simple将setter添加到数组中,每当值更改时,我重新加载tableView。

修改

只有在修改传递给GetDataForFruitsArrayThread

的inout fruits数组时,上述解决方案才有效
self.thread = GetDataForFruitsArrayThread(array: &fruits)

所以不要在GetDataForFruitsArrayThread中再创建一个数组属性,而是直接修改传递给GetDataForFruitsArrayThread的数组。