3

Why this code will trigger didSet when init

final public class TestDidSet {

static var _shared: TestDidSet! = TestDidSet()

func testA() { }

private var test = true {
    didSet {
        print("didSet test when initing!!!!!:\(test)")
    }
}
private var _value: Bool! {
    didSet {
        print("didSet when initing!!!!!:\(_value)")
    }
}

private init() {
    testSet()
    _value = false
    test = false
}

private func testSet() {
    _value = true
}
}

TestDidSet._shared.testA()

any idea? should it not trigger didSet? someone help!

update: My point of view is this, testSet() and _value = false is doing the same thing, but testSet() is outside init(), so testSet() will trigger didSet while _value = false not. Why?!

It's not optional type or other reason, that cause 'didSet', I suppose.

InvokerLaw
  • 91
  • 9
  • What do you want ? call testSet() will trigger your didSet, while assign value will not trigger your didSet in init function – Tony Nguyen May 25 '16 at 10:47
  • 2
    [This comment explains it nicely.](http://stackoverflow.com/questions/25230780/is-it-possible-to-allow-didset-to-be-called-during-initialization-in-swift#comment39303335_25231068) – Hamish May 25 '16 at 10:55
  • `didSet` is a setter in Swift same `- (void)setTest:(Bool)test;` in Objective-C. So it will call when you will assign any value to `test`. Its not an event its a setter. – TheTiger May 25 '16 at 11:07

2 Answers2

1

When you declare a property with an implicitly unwrapped optional type (Bool! in your case), it gets implicitly assigned a default value of nil. Then afterwards if you assign it with some other value in your initializer then the didSet observer gets triggered because it's already a second assignment. didSet is supposed to not be triggered only on a first one.

0x416e746f6e
  • 9,872
  • 5
  • 40
  • 68
  • 1
    It's nothing about how many time I using `_value = false`, it'll always not trigger `didSet` while this code is in `init()` – InvokerLaw May 27 '16 at 08:35
  • Yes, because the type of property is `Bool!`. If you change it to simple `Bool` (and make necessary adjustment for not being allowed to trigger instance methods before all properties were initialized), then you will notice that the very first assignment does not trigger the observer, and all consequent do. – 0x416e746f6e May 27 '16 at 10:20
-3

The didSet{} closure is called every time you assign a new value to your properties (even if you assign it at the declaration (inline) or at the initialisation).

Artheyn
  • 1,042
  • 10
  • 7
  • 1
    `The willSet and didSet observers of superclass properties are called when a property is set in a subclass initializer, after the superclass initializer has been called. They are not called while a class is setting its own properties, before the superclass initializer has been called.`, see: [developer.apple.com](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html#//apple_ref/doc/uid/TP40014097-CH14-ID262) – dkoch Sep 16 '17 at 06:48