在主线程以外的其他线程上更新UI是一个常见错误,可能会导致错过UI更新,视觉缺陷,数据损坏和崩溃。
https://developer.apple.com/documentation/code_diagnostics/main_thread_checker
示例:
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let data = data {
DispatchQueue.main.async { // Correct
self.label.text = "\(data.count) bytes downloaded"
}
}
}
task.resume()
我的问题从这里开始-
当我们说.async
表示与.main
不同时(或不并行)时,我对以上声明感到困惑。有人可以解释我的问题吗?
答案 0 :(得分:4)
#include <iostream>
#include <string>
#include <typeinfo>
unsigned short operator "" _ush(unsigned long long int a)
{
return static_cast<unsigned short>(a);
}
int main()
{
std::string name;
bool equal = typeid(decltype(123_ush)) == typeid(unsigned short); // check that literal is indeed unsigned short
std::cout << equal;
}
意味着您在主队列中排队一个任务,而无需等待该任务被执行。主队列任务将在操作系统计划的自动自动在主线程上运行。
将每个DispatchQueue.main.async
视为工作人员。调用DispatchQueue
会在工作人员的TODO列表下添加一个任务,不要等待工作人员完成任务。 .async
是在主线程上工作的特定工作程序。
另一方面,DispathQueue.main
将阻塞线程,直到任务块执行完毕。您可以在除主线程之外的任何其他线程上调用.sync
,因为不得阻塞主线程。
这并不意味着您无法致电.sync
。您可以像在非主线程上的任何自定义dispathQueue.sync一样调用DispatchQueue.main.sync。
例如
DispatchQueue.main.sync
可以。
但是
DispatchQueue(label: "bgqueue", qos: .background).async
{
DispatchQueue.main.sync{}
}
不是。
DispatchQueue.main.async{
DispatchQueue.main.sync{}
}
通常不是很有用。如果您希望在主队列任务之后发生某些事情,您也只需将该“事物”排队到主队列中。如果没有必要,则不值得阻塞线程。
话虽这么说,这是使用.sync
时要记住的两个规则,而不管哪个队列正在接收.sync
调用:
.sync
本身,这会导致死锁。 .sync
,这会阻塞UI线程。答案 1 :(得分:2)
我认为您对wb.Activate
wb.Sheets("PMCC 1").Select
For Each ws In wb.Worksheets
ws.Activate
index = index + 1
If index <= 10 Then
irow = ws.Cells(Rows.Count, 1).End(xlUp).Row
newtemp = Replace(ws.Name, " ", "#0")
For J = irow To 2 Step -1
If ws.Cells(J, 1) <> newtemp Then
ws.Cells(J, 1).EntireRow.Delete
End If
Next J
Else
irow = ws.Cells(Rows.Count, 1).End(xlUp).Row
newtemp = Replace(ws.Name, " ", "#")
For J = irow To 2 Step -1
If ws.Cells(J, 1) <> newtemp Then
ws.Cells(J, 1).EntireRow.Delete
End If
Next J
End If
Next ws
MsgBox ("Deleted")
的工作方式感到困惑。
DispatchQueue
只是管理线程池,当我们给它一个代码块执行时,它只是选择一个空闲线程并在其上运行那段代码。
因此,基本上一个线程可以被许多队列使用。队列只是一个任务列表,它管理将来将要执行的所有任务。
因此,基本上在这里,当您执行DispatchQueue
时,您只是在指示DispatchQueue.main.async
执行代码,而不必等待未决的任务执行。