Capturing "property"

I'm writing some swift UI code and I want to use .onChange(of: self.property), and know the old value of the property. The docs say to capture it using [property], which seems to work, but for the life of me I can't find a precise explanation of what happens when I spell it like that. If I write [self.property], I get an error "Expected 'weak', 'unowned', or no specifier in capture list."

The thing is, I like to be explicit when referencing properties by always prepending self..1 I can't figure out if there's a way to write a capture list that references self.property, and I’d like to know exactly what the compiler is doing in this case.

My guess is it's creating a copy named property and initializing it with the value of self.property at the time of capture. Is there any way to write that explicitly in the capture list? [prop = self.property]?

I’m not even sure what this would mean if property were a reference type. Does SwiftUI’s .onChange(of:) only works on value types?


1My preferred coding style is to spell symbols in a way that clues you in to their defining scope. In my C++ days, that meant member variables were prefixed with a lower-case m, and this-> was never used on members, and members were virtually always private. But because Swift properties are frequently public, I find it unappealing to name them mProperty (perhaps it makes me feel like I’m accessing a private member). So now I make a point of writing self.property everywhere.

1 Like

[prop = self.property] should work fine.

class Foo {
    var property = 0
    
    var getProperty: () -> Int {
        return { [prop = self.property] in prop }
    }
}
// compiles, works fine

You can learn more about capture list syntax in the Swift reference book.

As for how onChange works, it seems to check the equality of the previous value and the new value. So it runs the == operator on the previous value and the new value, and if the result is false, then the closure will run.

2 Likes

Thanks for that reference. I was looking at a different part of the book that talked about capture lists in some detail, but not enough. It didn't occur to me that there was more to be found elsewhere in the book. And it's just blind luck that I wrote that expression like that; I didn't realize it actually worked that way. Thanks!

1 Like
Terms of Service

Privacy Policy

Cookie Policy