`@ObservedObject` shound't be initialized inside the `SwiftUI.View`
Open
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 19.7k
- Forks
- 2.3k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 11
Description
New Issue Checklist
- Updated SwiftLint to the latest version
- I searched for existing GitHub issues
New Rule Request
Please describe the rule idea, format this issue's title as Rule Request: [Rule Name] and describe:
New Rule Request:
- Why should this rule be added?
Apple's documentation is explicit that a view must not create an@ObservedObject—@ObservedObjectdoesn't own the object's lifetime, so initializing one inside a View is unsafe:SwiftUIcan recreate the view at any time, which re-instantiates the object (silently resetting its state) and, during teardown/animation, can leaveSwiftUI's internal box referencing a deallocated object →EXC_BAD_ACCESSuse-after-free crashes (ObservedObjectPropertyBox.update→objc_msgSend). The correct wrappers are@StateObject(view owns it) or@Observable(Observation). This rule flags objects created inside an@ObservedObject.
- Apple: @ObserverdObject / @ObservedObject ("use @StateObject … to ensure consistent results" / don't create observed objects in a view) - "Don’t specify a default or initial value for the observed object. Use the attribute only for a property that acts as an input for a view, as in the above example."
- Hacking with Swift - "Tip: It is really important that you use @ObservedObject only with views that were passed in from elsewhere. You should not use this property wrapper to create the initial instance of an observable object – that’s what @StateObject is for.
- SwiftLee — @StateObject vs @ObservedObject
- Examples
Triggers a violation (object created in the view):
@ObservedObject var viewModel = ViewModel()
@ObservedObject private var loader = Loader(url: url)
init() { self._state = ObservedObject(wrappedValue: LoadState()) }
Does not trigger (injected, not created):
@ObservedObject var viewModel: ViewModel // set from init parameter
init(viewModel: ViewModel) { self.viewModel = viewModel }
@StateObject var viewModel = ViewModel() // owned via @StateObject
@State var model = Model() // @Observable model
-
Configurable?
Not. -
Opt-in or default?
Opt-in.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing existing SwiftUI-specific rule implementations and their rule tests, then use the provided violating and non-violating examples as fixtures. Add an opt-in rule that distinguishes objects initialized under @ObservedObject from injected properties, and verify that the examples produce the expected violations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100