I know, this is a very unusual thing to do, but I noticed that SwiftUI view won't update when a @State
property is assigned from a pointer:
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!")
}
}
}
}
The sortMyArr
is a dumb bubble sort in 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;
}
}
}
}
The view updates when using self.numbers.sort()
or self.numbers = self.numebers.sorted()
, but not the way I used above.
As a hack, I can update the view with
@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())
Is there a way to notice SwiftUI without such a hack? This can be a problem when a project uses a bridge to C/C++.
EDIT: The same happens for NSMutableArray
, using
self.someNSArray.sort(using: [NSSortDescriptor(key: "self", ascending: true)])