The main reason is for previews, models that are initialised with @StateObject are not initialised. WWDC 2020 Structure your app for SwiftUI previews
8:19
Secondly, the model changes, @StateObject will allow SwiftUI to detect the change and cause the body to be re-computed because model is referenced (twice) within the body, which SwiftUI knows by dependency tracking. This means that MailViewer and SettingsView will be re-created with the new data in the model. Then if anything changed in those View structs, SwiftUI will detect that by diffing the new structs from the ones returned previously and update the screen with whatever changes are needed to bring the screen up to date.
As you say, we can't guarantee structs to hang around, in fact they do not, they are created, the screen is rendered and they are thrown away. That is why we use property wrappers so when the struct is created again it is given the same data to use for the property. In the case of @StateObject the object is created once, the first time the body is computed of the first struct. If a struct is no longer being created, e.g. it is excluded by an if statement, then the object is deinit. If the struct is created again in the future then a new object is created, this is more of a feature for Views than for Apps. This means that the state object's life cycle is tied to the life cycle of the View being shown on screen which is very powerful.
If we were to use normal properties to init objects on SwiftUI structs then those objects would be created every time a struct is re-created which is a heap allocation which fills up RAM and slows down SwiftUI and should be avoided at all costs.