Property initializers run before 'self' is available
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
In Swift, stored property initializers run before the instance is fully initialized. That is why you get errors about self not being available when one property initializer tries to use another instance property or method too early.
This rule exists to keep initialization safe and predictable. Until all stored properties have valid initial values, Swift does not let you use the partially formed instance as though it were fully constructed.
Why self Is Not Available Yet
Consider a class like this:
This looks reasonable, but Swift rejects it because doubled is trying to read another instance property during stored-property initialization. At that point, the instance has not finished phase-one initialization, so self is not yet fully available.
Even though you did not write self.base, that is effectively what the compiler sees.
The Safe Fix: Use init
If one property depends on another, compute the dependent value inside the initializer.
Now the dependency is explicit and safe. By the time you assign doubled, you already have the value needed to calculate it.
Use lazy When the Property Can Be Deferred
If the property can wait until after initialization completes, lazy is often the right solution.
A lazy property is not initialized until first access, so self is available by then.
This is useful when the derived value is expensive, optional, or depends on the fully initialized instance.
Use a Computed Property When the Value Does Not Need Storage
Sometimes you do not need stored state at all. A computed property may be cleaner.
This is often the best option for simple derived values because it avoids initialization ordering issues entirely.
Structs Follow the Same Principle
The same rule applies to structs.
Again, initialization dependencies belong in init or in computed properties, not in stored-property initializers that depend on self.
Why Swift Is Strict Here
Swift’s two-phase initialization model prevents you from accidentally using an object before it is valid. Without this rule, code could read uninitialized memory or run logic against an incomplete instance.
The compiler error is not being overly cautious. It is enforcing a model that makes initialization bugs easier to prevent.
Once you understand that stored-property initializers must stand on their own, the restriction becomes much easier to work with.
Common Pitfalls
A common mistake is assuming that referencing another stored property inside a property initializer is just a compile-time shortcut. It still depends on self, so Swift blocks it.
Another mistake is using lazy for everything. lazy is useful, but if the value should always exist immediately, init or a computed property is often clearer.
Developers also sometimes move too much work into property initializers when that logic really belongs in initialization code.
Finally, remember that methods are also unavailable in this stage if calling them would require self. The rule is broader than property access alone.
Summary
- Stored property initializers run before
selfis fully available. - A stored property initializer cannot depend on another instance property or method.
- Use
initwhen one property depends on another during construction. - Use
lazywhen initialization can be deferred until after the instance exists. - Use computed properties when the value is derived and does not need separate storage.
Related reading
- Protocol can only be used as a generic constraint because it has Self or associatedType requirements
- Protocol can only be used as a generic constraint because it has Self or associatedType requirements
- Protocol doesn't conform to itself?
- Providing a default value for an Optional in Swift?
- Provisioning profile doesn't include the application-identifier and keychain-access-groups entitlements
- Published property wrapper not working on subclass of ObservableObject
- Pull to refresh UITableView without UITableViewController
- Push Notifications in Android Platform
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.