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被调用。
我希望只有foo的num被呼叫。
如果我删除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文档中提到它,因为一个结构是一个值类型,它会生成一个副本等(尽管起初我没有预料到)。
但其他的案子我不明白…

最佳答案

您可以通过与任何对象的一致性footype来解决这个问题。

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

10-08 12:12