为什么要调用此属性的didSet

时间:2016-04-12 08:56:23

标签: swift

protocol FooType {
    var num:Int { get set }
}

class Foo: FooType {
    var num: Int = 0 {
        didSet {
            print("Did set num")
        }
    }
}

class Bar {
    var foo: FooType = Foo() {
        didSet {
            print("Did set Foo")
        }
    }

    func changeNum(num:Int) {
        foo.num = num
    }
}

let bar = Bar()
bar.changeNum(5)

Did set num
Did set Foo

在这个例子中,在foo上设置一个属性导致Bar的didSet for foo被调用。

我希望只有Foo的num didSet才能被调用。

如果我将Bar的foo属性的协议约束删除为FooType,它的行为与我预期的一样。

protocol FooType {
    var num:Int { get set }
}

class Foo: FooType {
    var num: Int = 0 {
        didSet {
            print("Did set num")
        }
    }
}

class Bar {
    var foo = Foo() {
        didSet {
            print("Did set Foo")
        }
    }

    func changeNum(num:Int) {
        foo.num = num
    }
}

let bar = Bar()
bar.changeNum(5)

Did set num

如果我保持与FooType的一致性,但添加一个类约束(FooType:class),它也会按预期运行。

protocol FooType: class {
    var num:Int { get set }
}

class Foo: FooType {
    var num: Int = 0 {
        didSet {
            print("Did set num")
        }
    }
}

class Bar {
    var foo: FooType = Foo() {
        didSet {
            print("Did set Foo")
        }
    }

    func changeNum(num:Int) {
        foo.num = num
    }
}

let bar = Bar()
bar.changeNum(5)

Did set num

如果我完全删除协议并使Foo成为结构而不是类,我们将回到两个被调用的setter。

struct Foo {
    var num: Int = 0 {
        didSet {
            print("Did set num")
        }
    }
}

class Bar {
    var foo = Foo() {
        didSet {
            print("Did set Foo")
        }
    }

    func changeNum(num:Int) {
        foo.num = num
    }
}

let bar = Bar()
bar.changeNum(5)

Did set num
Did set Foo

在将Foo更改为结构的情况下,我可以看到它为什么会发生...它在swift文档中提到它,因为struct是一个值类型,它是一个副本等等(虽然我起初并没有期待它。

但其他情况我不会......

1 个答案:

答案 0 :(得分:0)

您可以通过使FooType符合AnyObject来解决此问题

protocol FooType: AnyObject {
    var num:Int { get set }
}