2016-06-02 6 views
4

habe ich dieses Verhalten beobachtet, das ich nicht ganz verstehe. Wenn Sie diesen Code auf einem Spielplatz Ausführung:willSet/didSet für die gespeicherte Eigenschaft eines Containers aufgerufen x Beim Festlegen einer Eigenschaft von 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" 

Wie oben ausgeführt, werden die willSet und didSet Blöcke genannt, obwohl die Eigenschaft selbst nicht gesetzt werden.

Auf der anderen Seite, wenn ich das Protokoll zu der Typklasse ändern

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

das Ergebnis ist, wie ich es sein (das heißt kein Aufruf zu willSet/didSet) folgt dann erwarten würde.

Was ist der Grund für dieses Verhalten?

Ich führe dies auf XCode 7.3.

Update: Noch in XCode 9.2/Swift 4

+0

Haben Sie das jemals gelöst? Das gleiche Problem sehen. – tombardey

+0

Ich bin egoistisch glücklich, endlich jemanden zu sehen, der in einem Kontext endet, wo dies Probleme verursacht;) Entschuldigung, aber nein, ich habe das nie anders gelöst, als die Dinge anders zu machen. – CMont

Antwort

0

Dies liegt daran, Testp leicht entweder class oder ein struct sein könnte. Wenn es sich um eine struct handelt, dann wird die Zuweisung testContainer.test.notes = "y" eine völlig neue Instanz von Testp Implementierer erstellen. Auf der anderen Seite, indem Sie protocol Testp: class machen, sagen Sie ausdrücklich, dass die Zuweisung zu notes die test nicht ändert.

Betrachten wir eine Funktion

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

Sie wissen nicht, innerhalb dieser Funktion wie TestContainer mit Klasse oder einer Struktur konfiguriert wurde. Ich denke, schnelle Team dachte, dass immer erhöhen will/didChange ist weniger verwirrend Verhalten ist solch ein Fall.

Verwandte Themen