我遇到了无法解决的线程问题。
private func addTextToOutputView(_ text: String){
var t = text
DispatchQueue.main.async {
var recentText = self.outputTextView.text
self.responseLogQueue.async {
if let firstChar = t.first, let index = t.index(of: firstChar) {
if firstChar == "\n" {
let subS = t[index...]
t = String(subS)
}
}
}
let currentTime = Date()
let currentTimeString = self.dateFormatter.string(from: currentTime)
t = "\n\(currentTimeString) \(t)"
recentText?.append(t)
self.outputTextView.text = recentText
if self.isScenarioOuputRunning {
if self.outputTextView.text.count > 0 {
let bottom = NSMakeRange(self.outputTextView.text.count-1, 1)
self.outputTextView.scrollRangeToVisible(bottom)
}
}
}
}
连接到发送大量数据且快速的BLE设备。
我需要按到达顺序显示数据。
这项工作一直到这里的某个点时,当数据过多时,应用程序都会卡住。
我只是不知道如何设置它以获取已经显示的数据(需要在主队列上执行此操作?)然后对其进行操作(在我自己的后端队列上),然后显示为已连接数据再次显示在屏幕上(文本视图)。
如果我将其封装在全局队列(我的队列)中,然后仅在主队列中调用get和set部分,则我尝试的所有操作都不会这样做,这会丢失部分数据,并且这样,我可以正确获取所有数据,但拥有的大量数据使应用程序卡在某个特定点
有人看到这个问题吗?
令人不安的是,在OBJ-C中,相同的代码(逻辑-逐行)正好工作!
答案 0 :(得分:1)
您编写的代码意义不大;您正在分派一些代码,这些代码将t
更新到另一个队列,但是随后在当前线程中使用t
来更新文本视图。另外,您分派到responseLogQueue
上的代码可以有效地t = String(t)
我建议您不要将textview本身用作数据模型。它应该只是存储在string属性中的文本视图。您可以使用串行分派队列来更新此字符串属性,并使用计时器来定期刷新UI:
class SomeViewController {
var outputTextView: UITextView!
private var refreshTimer: Timer?
private var outputText = ""
private var responseLogQueue: DispatchQueue!
override func viewDidLoad() {
super.viewDidLoad()
self.responseLogQueue = DispatchQueue(label:"ResponseLogQueue")
self.timer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true, block: { [weak self] (timer) in
guard let strongSelf = self else {
return
}
if self.isScenarioOuputRunning && !strongSelf.outputText.isEmpty {
strongSelf.outputTextView.text = strongSelf.outputText
let bottom = NSMakeRange(strongSelf.outputTextView.text.count-1, 1)
strongSelf.outputTextView.scrollRangeToVisible(bottom)
}
})
}
private func addTextToOutputView(_ text: String) {
let currentTimeString = self.dateFormatter.string(from: Date())
let newText = "\n\(currentTimeString) \(text)"
self.responseLogQueue.async {
self.outputText = self.outputText.append(newText)
}
}
}