Ich verstehe, dass set und get für berechnete Eigenschaften gelten (keine Sicherung von gespeicherten Eigenschaften ).
Wenn Sie von einem Objective-C kommen, denken Sie daran, dass sich die Namenskonventionen geändert haben. In Swift wird eine iVar- oder Instanzvariable als gespeicherte Eigenschaft bezeichnet
Beispiel 1 (schreibgeschützte Eigenschaft) - mit Warnung:
var test : Int {
get {
return test
}
}
Dies führt zu einer Warnung, da dies zu einem rekursiven Funktionsaufruf führt (der Getter ruft sich selbst auf). Die Warnung in diesem Fall lautet "Versuch, 'Test' in seinem eigenen Getter zu ändern".
Beispiel 2. Bedingtes Lesen / Schreiben - mit Warnung
var test : Int {
get {
return test
}
set (aNewValue) {
//I've contrived some condition on which this property can be set
//(prevents same value being set)
if (aNewValue != test) {
test = aNewValue
}
}
}
Ähnliches Problem - Sie können dies nicht tun, da der Setter rekursiv aufgerufen wird. Beachten Sie außerdem, dass sich dieser Code nicht über keine Initialisierer beschwert, da keine zu initialisierende Eigenschaft gespeichert ist .
Beispiel 3. Berechnete Lese- / Schreibeigenschaft - mit Hintergrundspeicher
Hier ist ein Muster, das die bedingte Einstellung einer tatsächlich gespeicherten Eigenschaft ermöglicht
//True model data
var _test : Int = 0
var test : Int {
get {
return _test
}
set (aNewValue) {
//I've contrived some condition on which this property can be set
if (aNewValue != test) {
_test = aNewValue
}
}
}
Hinweis Die tatsächlichen Daten heißen _test (obwohl es sich um beliebige Daten oder Datenkombinationen handeln kann). Beachten Sie auch die Notwendigkeit, einen Anfangswert anzugeben (alternativ müssen Sie eine init-Methode verwenden), da _test tatsächlich eine Instanzvariable ist
Beispiel 4. Verwenden von will und did set
//True model data
var _test : Int = 0 {
//First this
willSet {
println("Old value is \(_test), new value is \(newValue)")
}
//value is set
//Finaly this
didSet {
println("Old value is \(oldValue), new value is \(_test)")
}
}
var test : Int {
get {
return _test
}
set (aNewValue) {
//I've contrived some condition on which this property can be set
if (aNewValue != test) {
_test = aNewValue
}
}
}
Hier sehen wir, wie willSet und didSet eine Änderung in einer tatsächlich gespeicherten Eigenschaft abfangen. Dies ist nützlich zum Senden von Benachrichtigungen, Synchronisieren usw. (siehe Beispiel unten).
Beispiel 5. Konkretes Beispiel - ViewController Container
//Underlying instance variable (would ideally be private)
var _childVC : UIViewController? {
willSet {
//REMOVE OLD VC
println("Property will set")
if (_childVC != nil) {
_childVC!.willMoveToParentViewController(nil)
self.setOverrideTraitCollection(nil, forChildViewController: _childVC)
_childVC!.view.removeFromSuperview()
_childVC!.removeFromParentViewController()
}
if (newValue) {
self.addChildViewController(newValue)
}
}
//I can't see a way to 'stop' the value being set to the same controller - hence the computed property
didSet {
//ADD NEW VC
println("Property did set")
if (_childVC) {
// var views = NSDictionaryOfVariableBindings(self.view) .. NOT YET SUPPORTED (NSDictionary bridging not yet available)
//Add subviews + constraints
_childVC!.view.setTranslatesAutoresizingMaskIntoConstraints(false) //For now - until I add my own constraints
self.view.addSubview(_childVC!.view)
let views = ["view" : _childVC!.view] as NSMutableDictionary
let layoutOpts = NSLayoutFormatOptions(0)
let lc1 : AnyObject[] = NSLayoutConstraint.constraintsWithVisualFormat("|[view]|", options: layoutOpts, metrics: NSDictionary(), views: views)
let lc2 : AnyObject[] = NSLayoutConstraint.constraintsWithVisualFormat("V:|[view]|", options: layoutOpts, metrics: NSDictionary(), views: views)
self.view.addConstraints(lc1)
self.view.addConstraints(lc2)
//Forward messages to child
_childVC!.didMoveToParentViewController(self)
}
}
}
//Computed property - this is the property that must be used to prevent setting the same value twice
//unless there is another way of doing this?
var childVC : UIViewController? {
get {
return _childVC
}
set(suggestedVC) {
if (suggestedVC != _childVC) {
_childVC = suggestedVC
}
}
}
Beachten Sie die Verwendung von BEIDEN berechneten und gespeicherten Eigenschaften. Ich habe eine berechnete Eigenschaft verwendet, um zu verhindern, dass derselbe Wert zweimal festgelegt wird (um zu verhindern, dass schlimme Dinge passieren!). Ich habe willSet und didSet verwendet, um Benachrichtigungen an viewController weiterzuleiten (siehe UIViewController-Dokumentation und Informationen zu viewController-Containern).
Ich hoffe das hilft und bitte jemanden schreien, wenn ich hier irgendwo einen Fehler gemacht habe!
get
&set
) besteht im Wesentlichen darin, eine Eigenschaft basierend auf einer anderen Eigenschaft berechnen zu lassen, z. B. die Umwandlung eines Etikettstext
in ein JahrInt
.didSet
&willSet
gibt es zu sagen ... hey, dieser Wert wurde gesetzt, jetzt machen wir das, zB Unsere dataSource wurde aktualisiert ... also lasst uns die tableView neu laden, damit sie neue Zeilen enthält. Ein weiteres Beispiel finden Sie in der Antwort von dfri, wie Sie Delegierte anrufen könnendidSet