Возможная проблема параллелизма с ForEach и массивом @StateIOS

Программируем под IOS
Ответить
Anonymous
 Возможная проблема параллелизма с ForEach и массивом @State

Сообщение Anonymous »

Я добавил ниже запись экрана, чтобы проблема стала еще яснее. Меня не устраивают текущие ответы, потому что я не понимаю, почему привязки (асинхронные) обновляются по-разному при работе с массивами и гораздо надежнее при работе с отдельными структурами (даже если они одного типа)
Изображение

- -
Я пишу базовый таймер обратного отсчета для iOS, используя try await Task.sleep(for: .секунды(1)) перед обновлением переменной @State. Когда переменная MyStruct, кажется, обновляется нормально, но если я помещу несколько MyStruct в массив, то я получу странные тайминги для обновлений, которые нарушат функциональность базового таймера обратного отсчета.< /p>
Вот мой отдельный пример: вам, возможно, придется обновить приложение несколько раз или заменить мой onAppear с помощью кнопки, чтобы увидеть, насколько непоследовательно это поведение.< /p>

Код: Выделить всё

import SwiftUI

struct ContentView: View {
@State var first = MyStruct(setTime: 15)
@State var second = MyStruct(setTime: 10)
@State var third = MyStruct(setTime: 5)

@State var array = [MyStruct(setTime: 15), MyStruct(setTime: 10), MyStruct(setTime: 5)]

@State var hasNotAppearedYet = true

var body: some View {
VStack {
Text("Seconds: \(Int(array[0].currentTime))").padding().font(.title3)
Text("Seconds: \(Int(array[1].currentTime))").padding().font(.title3)
Text("Seconds: \(Int(array[2].currentTime))").padding().font(.title3)

Divider()

Text("Seconds: \(first.currentTime)").padding().font(.title3)
Text("Seconds: \(second.currentTime)").padding().font(.title3)
Text("Seconds: \(third.currentTime)").padding().font(.title3)
}
.padding()
.onAppear(){
if(hasNotAppearedYet){
$array[0].startTimer(name: "arrayElement0")
$array[1].startTimer(name: "arrayElement1")
$array[2].startTimer(name: "arrayElement2")

$first.startTimer(name: "FIRST")
$second.startTimer(name: "SECOND")
$third.startTimer(name: "THIRD")

hasNotAppearedYet = false
}
}
}
}

struct MyStruct {
var setTime: Double
var currentTime: Double = 0
}

extension Binding {
func startTimer(name: String){
Task {
wrappedValue.currentTime = wrappedValue.setTime
print(name, wrappedValue.currentTime)

while (wrappedValue.currentTime > 0) {
try await Task.sleep(for: .seconds(1))
try Task.checkCancellation()
wrappedValue.currentTime -= 1
print(name, wrappedValue.currentTime)
}
}
}
}

#Preview {
ContentView()
}
Одинаковые странные результаты в симуляторе и на реальном iPhone.


Подробнее здесь: https://stackoverflow.com/questions/782 ... y-of-state
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»