Я хочу запустить тяжелую для цикла в фоновом режиме, и каждый раз, когда одна итерация заканчивается, обновляйте оставшийся счет в основном потоке.
Следующий код работает, как и ожидалось. < /p>
// 1
DispatchQueue.global(qos: .utility).async {
for i in 0...100 {
self.heavyTask()
// update label on main thread
DispatchQueue.main.async {
self.label.text = "\(100 - i) left"
}
}
}
< /code>
Однако, когда я переписываю его, используя задачу, она не работает, как ожидалось. >
// 2
Task(priority: .utility) {
for i in 0...100 {
heavyTask()
// update label on main thread
Task { @MainActor in
label.text = "\(100 - i) left"
}
}
}
< /code>
Если я переписываю только часть этого, используя задачу, как показано ниже, он работает, как и ожидалось. ">// 3
DispatchQueue.global(qos: .utility).async {
for i in 0...100 {
self.heavyTask()
// update label on main thread
Task { @MainActor in
self.label.text = "\(100 - i) left"
}
}
}
< /code>
Я не могу понять, почему второй код не работает, как и ожидалось.
Пожалуйста, помогите мне. < /p>
Весь код заключается в следующем.import UIKit
class ViewController: UIViewController {
private let label = UILabel()
private let button = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemCyan
label.frame.size = .init(width: 200, height: 100)
label.frame.origin = .init(x: 100, y: 100)
view.addSubview(label)
button.setTitle("run", for: .normal)
button.frame.size = .init(width: 200, height: 100)
button.frame.origin = .init(x: 100, y: 200)
button.addTarget(self, action: #selector(didTapButton), for: .touchUpInside)
view.addSubview(button)
}
@objc
private func didTapButton(sender: UIButton) {
label.text = "start"
DispatchQueue.global(qos: .utility).async {
for i in 0...100 {
self.heavyTask()
DispatchQueue.main.async {
self.label.text = "\(100 - i) left"
}
}
}
}
private func heavyTask() {
var count = 0
for _ in 0...200_000 {
count += 1
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/794 ... k-in-swift