簡體   English   中英

為什么要調用此屬性的didSet

[英]Why is this property's didSet being called

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是一個值類型,它是一個副本等等(盡管我最初沒想到它) )。

但其他情況我不明白......

你可以通過一致性FooType到AnyObject來解決這個問題

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM