Avihu Turzion
Avihu Turzion

Reputation: 3414

WillSet is called when I read a property

I have a weird situation in Swift 2 where in a certain situation when I reference a property, the property's set observers are called.

The following code sample illustrates the issue:

var i = 0

protocol PropertyProtocol {
  var name: String { get }
}

class PropertyType: PropertyProtocol {
  var name = "Bob"
}

class AggregateType {
  var prop: PropertyProtocol! {
    willSet {
      i += 1
      print("a set will be done")
    }
  }
}

let a = AggregateType()
i                          // i = 0, since prop was not set.
a.prop = PropertyType()
i                          // i = 1, since prop was just set.

// This is where it gets weird
a.prop.name
i                          // i = 2
a.prop.name
i                          // i = 3

This problem doesn't appear prior to Swift 2, as this same code in Xcode 6.4 doesn't reproduce the issue, but keeps i = 1 no matter how many times a.prop.name is called.

A temporary workaround I have found for this issue is transferring the internal property to another temporary variable in the current scope and referencing its internal properties using the temp var.

i                          // i = 1
let prop = a.prop
prop.name
i                          // 1 = 1

But this makes my code uglier for no reason other than to compensate for this bug.

Anyone knows of this issue? Is there anyway to solve this more fundamentally?

Upvotes: 3

Views: 132

Answers (1)

Martin R
Martin R

Reputation: 539695

That's a bug which has been fixed in Xcode 7.2 beta 2. From the release notes:

In previous releases of Swift, if a type had a mutable property of protocol type, "chained" accesses to properties of that property were always treated as mutations of the property, even if the second property was only read, not written.
...
The workaround was to split the access into separate expressions ...
...
This bug has now been fixed. (22953072)

The workaround suggested here is exactly what you already figured out.

Upvotes: 6

Related Questions