2016-06-02 2 views
4

Я наблюдал за поведением, которое я не совсем понимаю. При выполнении этого кода в детской площадке:willSet/didSet вызвал сохраненное свойство контейнера x при настройке свойства x

protocol Testp { 
    var notes: String { get set } 
} 

class Testc: Testp { 
    var notes: String = "x" 
} 

class TestContainer { 
    var test: Testp = Testc() { 
     willSet { 
      print("willSet") 
     } 
     didSet { 
      print("didSet") 
     } 
    } 
} 

var testContainer = TestContainer() 
print(testContainer.test.notes) // prints "x" 

// this triggers a willSet+didSet call on TestContainer's 
// stored property, even though "test" is not changed in testContainer 
testContainer.test.notes = "y" 

print(testContainer.test.notes) // prints "y" 

Как отметил выше, willSet и didSet блоки называются даже если сам объект недвижимости не установлен.

С другой стороны, если я изменить протокол быть класса типа, как следовать

protocol Testp: class { 
    var notes: String { get set } 
} 

то результат, как я бы ожидать, что она не будет (т.е. не вызов willSet/didSet).

В чем причина такого поведения?

Я запускаю это на XCode 7.3.

Обновление: Тем не менее, в XCode 9.2/Swift 4

+0

Вы когда-нибудь разрешали это? См. Ту же проблему. – tombardey

+0

Я эгоистично рад наконец-то увидеть, как кто-то еще попал в контекст, где это вызвало проблемы;) Извините, но нет, я никогда не решал это иначе, чем делать что-то по-другому. – CMont

ответ

0

Это потому, что Testp легко может быть либо class или struct. Если это struct, то назначить testContainer.test.notes = "y" создаст совершенно новый экземпляр исполнителя Testp. С другой стороны, делая protocol Testp: class, вы прямо указываете, что присвоение notes не изменит test.

Рассмотрит функцию

func doSomething(_ container: TestContainer) { 
    testContainer.test.notes = "y" 
} 

Вы не знаете, в этой функции, как TestContainer была настроена с классом или структурой. Я думаю, что быстрая команда считала, что всегда поднимать will/didChange менее запутанной задачей является такой случай.

Смежные вопросы