从其他线程通知UITable



我有一个简单的UITable实现和一个名为fruits的数组。取自本例。唯一的区别是,我使用UIViewController来代替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函数。在函数中,我调用一个线程,该线程将数组作为参数。线程正在异步地用新值填充数组。意味着我不知道是否会有任何值,也不知道该值何时出现并设置到数组中。因此,您可以想象我在这一点上想问的问题:一旦视图将数组加载到UITableView中,我如何向UITableView发出信号,表明我已经更改了数组的内容。在c#中有一个NotifyAll()函数,它将所有侦听器都声明为一个属性。有没有一种简单而高效的方法可以在不导入任何非包含库的情况下快速完成这项工作?

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)
}
}
}

编辑-2017年11月21日:

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

@IBOutlet weak var tableView1: UITableView!
var fruits : [String] = Array() {
didSet {
self.tableView1.reloadData()
}
}

问题:我正在GetDataForFruitsArrayThread类中的array.append(fruit)处设置断点。之后,在didSet方法中有一个断点。但是这个断点在append()-调用之后不会被调用!注意:GetDataForFruitsArrayThread类的init函数上的参数是一个输入输出参数!

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

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

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

我在做什么?Simple在数组中添加了一个setter,每当值发生变化时,我都会重新加载tableView。

编辑:

只有当您修改传递给GetDataForFruitsArrayThread的inout水果数组时,上述解决方案才会起作用

self.thread = GetDataForFruitsArrayThread(array: &fruits)

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

最新更新