# Deferred property wrappers

**URL:** <https://forums.swift.org/t/deferred-property-wrappers/38931>\
**Category:** Pitches\
**Tags:** properties\
**Created:** [July 31, 2020, 12:51pm UTC](https://forums.swift.org/t/deferred-property-wrappers/38931 "2020-07-31T12:51:46Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![richard-clements](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/richard-clements/32/12698_2.png) [@richard-clements](https://forums.swift.org/u/richard-clements)\
**Post date:** [July 31, 2020, 12:51pm UTC](https://forums.swift.org/t/deferred-property-wrappers/38931/1 "2020-07-31T12:51:46Z")

</div>

I wanted to make a pitch for a deferred style of property wrapper, that will work with lazy properties only. The purpose is that you would be able to use another (non lazy) property as a dependency for the property wrapper.

Currently we can get around this by using a class for the property wrapper, then after initialisation setting the dependency on the property wrapper. For example:

```swift
@propertyWrapper
class Foo<Baz, Bar, Value> {
    let baz: Baz
    var bar: Bar?

    var wrappedValue: Value? {
        get { bar?.get(baz) }
        set { bar?.set(newValue, for: baz)
    }

    init(baz: Baz) { 
        self.baz = baz
    }

    func configure(bar: Bar) {
        self.bar = bar
    }
}

```

This, however means after initialisation you have to run through all `@Foo` properties to then configure `bar`.

```swift
class Item {
    let bar: Bar
    
    @Foo(baz: Baz())
    var property: Value

    init(bar: Bar) {
        self.bar = bar
        _property.configure(bar: bar)
    }
}

```

# Proposed Solution

Add a deferredPropertyWrapper which allows the usage of `self` in the initialiser of the property wrapper. Make it required that the property is marked with `lazy` so that the user is aware that the property wrapper is deferred until after initialisation.

```swift
@deferredPropertyWrapper
struct Foo<Baz, Bar, Value>
    let baz: Baz
    let bar: Bar
    
    var wrappedValue: Value {
        get { bar.get(baz) }
        set { bar.set(baz) }
    }

```

Then when you want to use the property wrapper you can use another non lazy property of `self`

```swift
class Item {
    let bar: Bar
    
    @Foo(baz: Baz(), bar: bar)
    lazy var property: Value
}

```

---

<div class="post-metadata">

**Author:** ![SwiftUI](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/swiftui/32/24361_2.png) [@SwiftUI](https://forums.swift.org/u/SwiftUI)\
**Post date:** [July 31, 2020, 12:56pm UTC](https://forums.swift.org/t/deferred-property-wrappers/38931/2 "2020-07-31T12:56:03Z")

</div>

Why not just call it `@lazyPropertyWrapper`, like `lazy[H/V]Stack`?

---

<div class="post-metadata">

**Author:** ![richard-clements](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/richard-clements/32/12698_2.png) [@richard-clements](https://forums.swift.org/u/richard-clements)\
**Post date:** [July 31, 2020, 1:00pm UTC](https://forums.swift.org/t/deferred-property-wrappers/38931/3 "2020-07-31T13:00:49Z")

</div>

My initial thinking for deferred would be that it shows that the wrapper would be initialised immediately after `init` had completed. `@lazyPropertyWrapper` however would play nicer with the use of `lazy var` though. Unless it made more sense to create a `deferred` property that is simply any property that is initialised immediately after `self` is.

---

<div class="post-metadata">

**Author:** ![David\_Catmull](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/david_catmull/32/1007_2.png) [@David\_Catmull](https://forums.swift.org/u/David_Catmull)\
**Post date:** [July 31, 2020, 3:08pm UTC](https://forums.swift.org/t/deferred-property-wrappers/38931/4 "2020-07-31T15:08:02Z")

</div>

I like this because it sounds like it would help with the one case that I've tried using property wrappers for so far: a string property that wraps the string value of a text field (and similarly for checkboxes). It's convenient to use, but setup requires a bunch of boilerplate initialization after my IBOutlets have been connected. If that initialization could happen automatically it would be really nice.

---

<div class="post-metadata">

**Author:** ![davidbjames](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/davidbjames/32/13850_2.png) [@davidbjames](https://forums.swift.org/u/davidbjames)\
**Post date:** [February 7, 2022, 9:38am UTC](https://forums.swift.org/t/deferred-property-wrappers/38931/5 "2022-02-07T09:38:15Z")

</div>

I _really_ need something like this. Seems missing in Swift. Frequently I want to access self or use some lazy loading pattern and it's frustrating why the limitation that we can't have:

```swift
@MyWrapper lazy var foo = (something that causes an extra allocation, or needs access to self) 

```

I'm in a situation now where I have a property wrapper to CurrentValueSubject which I want lazy loaded (the subject), but then I get "exclusive access" crashes because the `wrappedValue` getter is implicitly mutating (tldr; a write to the subject causes a view to reload which reads from the value _after_ the write). I can mark the accessor as `nonmutating` but then I can't have the subject lazy loaded (catch 22). If I could just mark the whole PW as `lazy` (instead of the inner subject) the problem would be solved.
