У меня есть представление, которое зависит как от @ObservedObject
, так и от @State
.
. В действии кнопки я изменяю их обоих, и это приводит к созданию sh. Если я изменяю только @ObservedObject, то все в порядке (за исключением того, что я, конечно, не получаю нужного поведения).
public struct PointListEditorView: View {
@ObservedObject var viewModel: PointListEditorViewModel
@State var selectedCellIndex: Int = NO_CELL_SELECTED_INDEX
public var body: some View {
(...)
Button(action: {
let savedSelectedCellIndex = self.selectedCellIndex
self.selectedCellIndex = NO_CELL_SELECTED_INDEX // No crash if I remove this line
self.viewModel.removePointEditorViewModel(at: savedSelectedCellIndex)
},
label: (...)
Что происходит, если у меня есть cra sh в body
подпредставления после вызова removePointEditorViewModel
. Это тело проходит через массив объектов, который изменяется removePointEditorViewModel
. removePointEditorViewModel
запускает переменные @Published в @ ObservedObject.
То же самое происходит, если я инвертирую обе строки следующим образом:
self.viewModel.removePointEditorViewModel(at: savedSelectedCellIndex)
self.selectedCellIndex = NO_CELL_SELECTED_INDEX//##
Сначала я подумал, что будет какое-то странное помехи между @State и @ObservedObject, но первые ответы (спасибо, ребята) указали мне в другом направлении.
Правка для получения дополнительной информации
Правка 2 , чтобы сделать заголовок и остальные в соответствии с текущими исследованиями
Вот иерархия моих представлений:
PointListEditorView
+ PointListEditorContentView
+ PointListEditorCellView (n times)
В PointListEditorView есть selectedCellIndex @State. Это состояние связывается с помощью PointListEditorContentView и PointListEditorCellView. Он изменяется через PointListEditorCellView через tapGesture.
Я зарегистрировал вход и выход из вычисления тела. Я также зарегистрировал создание PointListEditorCellView, и когда я удалил вещи в моей модели. Я заметил некоторые странные вещи.
**APP START**
Enter PointListEditorView body
Exit PointListEditorView body
Enter PointListEditorContentView body
count of pointEditorViewModels : 0
count of pointEditorViewModelsAndIndex : 0
End preparation PointListEditorContentView body
Exit PointListEditorContentView body
**ADD ONE CELL**
Enter PointListEditorContentView body
count of pointEditorViewModels : 1
map call with index : 0
count of pointEditorViewModelsAndIndex : 1
End preparation PointListEditorContentView body
Exit PointListEditorContentView body
created PointListEditorCellView : 35779A71-811F-42DD-A803-3C0E82C3CAD8
Enter PointListEditorCellView body : 35779A71-811F-42DD-A803-3C0E82C3CAD8
Exit PointListEditorCellView body
Enter PointListEditorView body
Exit PointListEditorView body
Все это выглядит довольно нормально для меня. Но теперь:
**SELECT THE CELL**
Enter PointListEditorView body
Exit PointListEditorView body
Enter PointListEditorContentView body
count of pointEditorViewModels : 1
map call with index : 0
count of pointEditorViewModelsAndIndex : 1
End preparation PointListEditorContentView body
Exit PointListEditorContentView body
Enter PointListEditorCellView body : 35779A71-811F-42DD-A803-3C0E82C3CAD8
<== Why the hell do we have that ???
This is the cell view created at previous step. It
should be forgotten and replaced by another one
as seen below
Exit PointListEditorCellView body
created PointListEditorCellView : 2EA80249-67B6-46A0-88C9-C5F5E8FEAE80
Enter PointListEditorCellView body : 2EA80249-67B6-46A0-88C9-C5F5E8FEAE80
Exit PointListEditorCellView body
**DELETE THE CELL**
Enter delete callback
Delete model element
@Published var modified, the view is notified
Exit delete callback
Enter PointListEditorView body
Exit PointListEditorView body
Enter PointListEditorContentView body
count of pointEditorViewModels : 0
count of pointEditorViewModelsAndIndex : 0
<== This shows there is nothing in the model, there should be
no cell view created - just like during app init
End preparation PointListEditorContentView body
Exit PointListEditorContentView body
Enter PointListEditorCellView body : 2EA80249-67B6-46A0-88C9-C5F5E8FEAE80
Fatal error: Index out of range: file /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.8.25.8/swift/stdlib/public/core/ContiguousArrayBuffer.swift, line 444
<== This "ghost" cell is refering to a model elemnt that
has been deleted, os of course there is a crash, but why
does this cell still exist ???
После еще нескольких расследований мне удалось обнаружить, что «сохранение» происходит только тогда, когда к представлению ячейки прикреплен tapGesture. Это делается в представлении PointListEditorContentView следующим образом:
struct PointListEditorCellView: View
var pointEditorViewModel: PointEditorBaseViewModel
var index: Int
@Binding var selectedCellIndex: Int
var body: some View {
VStack(spacing: 3.0) {
PointEditorView(pointEditorViewModel)
.onTapGesture {
if (self.selectedCellIndex == self.index) {
self.selectedCellIndex = NO_CELL_SELECTED_INDEX
} else {
self.selectedCellIndex = self.index
}
}
}
}
Если я удалю .gesture, я не вижу появления призрака.