SwiftUI не refre sh с массивом, инициализированным указателем или NSMutableArray - PullRequest
0 голосов
/ 27 апреля 2020

Я знаю, это очень необычная вещь, но я заметил, что представление SwiftUI не будет обновляться, когда свойство @State назначено указателем:

struct ContentView: View {
    @State private var numbers: [Int32] = []

    var body: some View {
        VStack {
            Text("\(numbers.description)")

            Button(action: {
                self.numbers.append(Int32.random(in: 0..<1000))
            }) {
                Text("Add a random number!")
            }

            Button(action: {
                var pointer: UnsafeMutableBufferPointer<Int32>!
                self.numbers.withUnsafeBufferPointer {
                    pointer = UnsafeMutableBufferPointer(mutating: $0)
                    sortMyArr(pointer.baseAddress!, Int32(self.numbers.count))
                }
                self.numbers = Array(pointer)
            }) {
                Text("Sort!")
            }
        }
    }
}

sortMyArr это глупая пузырьковая сортировка в C:

void sortMyArr(int *arr, const int size)
{
    for (int i = 0; i < size; ++i) {
        for (int j = i; j < size; ++j) {
            if (arr[i] < arr[j]) {
                int tmp = arr[i];
                arr[i] = arr[j];
                arr[j] = tmp;
            }
        }
    }
}

Представление обновляется при использовании self.numbers.sort() или self.numbers = self.numebers.sorted(), но не так, как я использовал выше.

Как hack , я могу обновить представление с помощью

    @State private var numbers: [Int32] = [] {
        didSet { self.needsUpdate = true }
    }
    @State private var needsUpdate = false {
        didSet { if self.needsUpdate { self.needsUpdate = false } }
    }

    // body view ...
    .background(Text("\(needsUpdate).description)").hidden())

Есть ли способ заметить SwiftUI без такого взлома? Это может быть проблемой, когда проект использует мост к C / C ++.

РЕДАКТИРОВАТЬ: То же самое происходит для NSMutableArray, используя

self.someNSArray.sort(using: [NSSortDescriptor(key: "self", ascending: true)])
...