Problem mit speichern von Daten im Model bzw Property List

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Problem mit speichern von Daten im Model bzw Property List

    Hallo liebe Gemeinde,

    ich habe eine RoofGeometry.swift Datei mit Properties und Computed Properties, die durch einen Controller RoofProfilController.swift geändert und berechnet werden.
    Das funktioniert auch sehr gut dank @tsunamix, ganz großen dank nochmal an dieser Stelle. Nun habe ich einen weiteren Controller TimberdimensionsController wo die Holzabmaße eingetragen/geändert werden, die man zum berechnen benötigt, der greift auch auf die RoofGeometry.swift zu. Aber die Werte werden scheinbar nicht in der RoofGeometry.swift gespeichert. Wenn ich auf den anderen Controller wieder gehe wird nicht mit den neuen Werten gerechnet.

    Nun habe ich nach Daten speichern im Inet und in meinem Buch "Swift 2.0" von Herrn Kofler gesuch und bin auf NSUserDefaults und Property List gestoßen, bin ich da auf dem richtigen Weg oder eher auf dem Holzweg?

    Danke schonmal für eure Hilfe und ein frohes Osterfest gewünscht.

    matze
  • Ui, das geht ja runter wie Öl... :saint:

    Schwer nach Deiner Beschreibung zu sagen, was da genau los ist. Mein erster Gedanke war jetzt, daß Du in den beiden Controllern zwei unterschiedliche Instanzen von RoofGeometry anlegst. Wenn das so ist, fallen mir auf die Schnelle zwei Möglichkeiten ein:

    1.) Du machst RoofGeometry zu einem Singleton / Shared Instance (wohl nicht das was man hier erwarten würde, aber ein recht einfacher Weg).
    2.) Du instanzierst RoofGeometry im AppDelegate und greifst dann in den Controllern über UIApplication.sharedApplication().delegate.myRoofGeometry drauf zu.

    NSUserDefaults ist definitiv nicht der richtige Weg. Das ist für andere Zwecke gedacht. Z.B. um Einstellungen über Programmstarts hinweg zu speichern.

    PS: BTW, schöne Ostertage allerseits.
  • Ist ganz einfach:

    C-Quellcode

    1. class Foo {
    2. var a = 0
    3. static let sharedFoo = Foo()
    4. }
    Instanziiert wird dann mit let foo = Foo.sharedFoo.

    Ich würde mich aber wohl eher für Nr. 2 entscheiden.

    Ist denn das andere Problem mit den gegenseitigen Abhängigkeiten der properties in RoofGeometry inzwischen überhaupt komplett gelöst?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von torquato ()

  • tsunamix schrieb:

    Ist ganz einfach:

    C-Quellcode

    1. class Foo {
    2. var a = 0
    3. static let sharedFoo = Foo()
    4. }
    Instanziiert wird dann mit let foo = Foo.sharedFoo.

    Ich würde mich aber wohl eher für Nr. 2 entscheiden.

    Ist denn das andere Problem mit den gegenseitigen Abhängigkeiten der properties in RoofGeometry inzwischen überhaupt komplett gelöst?
    Ob das threadsafe ist?

    Der übliche Ansatz verwendet schon GCD.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Erstmal großen Dank für eure antworten, das hilft mir immer beim suchen in meinem Buch und dort bin ich auch erstmal fündig geworden warum sich meine App so verhält.
    Ein ViewController ist sozusagen ein Wegwerfobjekt, sobald ich in eine andere Ansicht wechsele wird die andere aus dem speicher geschmissen und somit meine Änderungen verworfen.
    Daraus folgt ich muß meiner App erklären du hast Änderungen zu speichern.

    Hab ich den Hintergrund so richtig verstanden?
  • Amin Negm-Awad schrieb:

    tsunamix schrieb:

    Ist ganz einfach:

    C-Quellcode

    1. class Foo {
    2. var a = 0
    3. static let sharedFoo = Foo()
    4. }
    Instanziiert wird dann mit let foo = Foo.sharedFoo.

    Ich würde mich aber wohl eher für Nr. 2 entscheiden.

    Ist denn das andere Problem mit den gegenseitigen Abhängigkeiten der properties in RoofGeometry inzwischen überhaupt komplett gelöst?
    Ob das threadsafe ist?
    Der übliche Ansatz verwendet schon GCD.
    Das ist hier eine Property. Genauso gut könntest Du fragen, ob var a = 0 threadsafe ist. Mit anderen Worten: Du könntest diese Frage so ziemlich bei JEDEM Code stellen, der hier gepostet wird, bei JEDER property.
    In dem hier gegebenen Kontext auch irrelevant. Seit wann laufen ViewController in unterschiedlichen Threads.

    Trotzdem interessante Frage. Wie ist das überhaupt mit Threadsafetyness in Swift? Ich habe mich noch nicht damit beschäftigt.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von torquato ()

  • matze511 schrieb:

    Erstmal großen Dank für eure antworten, das hilft mir immer beim suchen in meinem Buch und dort bin ich auch erstmal fündig geworden warum sich meine App so verhält.
    Ein ViewController ist sozusagen ein Wegwerfobjekt, sobald ich in eine andere Ansicht wechsele wird die andere aus dem speicher geschmissen und somit meine Änderungen verworfen.
    Daraus folgt ich muß meiner App erklären du hast Änderungen zu speichern.

    Hab ich den Hintergrund so richtig verstanden?
    Pack's in den Appdelegate. Die UIApplication-Instanz bleibt die ganze Zeit bestehen. Etwa so:

    C-Quellcode

    1. class AppDelegate: UIResponder, UIApplicationDelegate {
    2. let roofGeometry = RoofGeometry()
    3. }
    4. class ViewController: UIViewController {
    5. var roofGeometry: RoofGeometry!
    6. override func viewDidLoad() {
    7. super.viewDidLoad()
    8. roofGeometry = (UIApplication.sharedApplication().delegate as! AppDelegate).roofGeometry
    9. }
    10. }
    Alles anzeigen
  • tsunamix schrieb:

    Amin Negm-Awad schrieb:

    tsunamix schrieb:

    Ist ganz einfach:

    C-Quellcode

    1. class Foo {
    2. var a = 0
    3. static let sharedFoo = Foo()
    4. }
    Instanziiert wird dann mit let foo = Foo.sharedFoo.

    Ich würde mich aber wohl eher für Nr. 2 entscheiden.

    Ist denn das andere Problem mit den gegenseitigen Abhängigkeiten der properties in RoofGeometry inzwischen überhaupt komplett gelöst?
    Ob das threadsafe ist?Der übliche Ansatz verwendet schon GCD.
    Das ist hier eine Property. Genauso gut könntest Du fragen, ob var a = 0 threadsafe ist. Mit anderen Worten: Du könntest diese Frage so ziemlich bei JEDEM Code stellen, der hier gepostet wird, bei JEDER property.In dem hier gegebenen Kontext auch irrelevant. Seit wann laufen ViewController in unterschiedlichen Threads.

    Trotzdem interessante Frage. Wie ist das überhaupt mit Threadsafetyness in Swift? Ich habe mich noch nicht damit beschäftigt.
    Nein, kann ich nicht. Eine Shared-Instance ist *per definitionem* applikationsglobal und daher in jedem Thread bekannt. Das gilt weder für lokale Variablen noch für Properties.

    Wenn es um einen View-Controller geht, ist eine Shared-Instance bereits der falsche Ansatz.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Amin Negm-Awad schrieb:

    Eine Shared-Instance ist *per definitionem* applikationsglobal und daher in jedem Thread bekannt. Das gilt weder für lokale Variablen noch für Properties.

    Ich vermute, Dir ist nicht ganz klar was static in Swift heißt. Mit static werden in Swift properties und Funktionen der Klasse deklariert, nicht Properties oder Funktionen der Instanzen. Die Klasse, sowie die Properties einer Klasse existieren nur einmal - threadübergreifend.

    Amin Negm-Awad schrieb:

    Wenn es um einen View-Controller geht, ist eine Shared-Instance bereits der falsche Ansatz.

    Es geht um das Datenmodell, auf das von verschiedenen ViewControllern aus zugegriffen werden soll. Da kann man das unter Umständen machen. Ich habe mehrmals im Thread gesagt, daß ein anderer Ansatz besser wäre.
  • Oh bitte bitte nicht streiten, hab mir den abschnitt im Buch auch mit der Vorgabe von @tsunamix durchgelesen, denn ich möchte nicht nur "copy and paste" machen sondern wenigstens auch in groben Zügen verstehen was ich da eigendlich mache bzw. die App macht.
    So funtioniert es aber wunderbar mit dem Eintrag in die AppDelegate und in den beiden ViewControllern.


    tsunamix schrieb:

    Ist denn das andere Problem mit den gegenseitigen Abhängigkeiten der properties in RoofGeometry inzwischen überhaupt komplett gelöst?
    Ja es funktioniert nun, hab es auch in dem anderen thread geschrieben und so hier gelöst:

    C-Quellcode

    1. if(myTextField.text == "Traufhö-Vordach-Neigung") {
    2. switch sender {
    3. case GrundmaßTextField:
    4. roofGeometry.Grundmaß = newValue
    5. case TraufhöheTextField:
    6. roofGeometry.Traufhöhe = newValue
    7. case VordachlängeTextField:
    8. roofGeometry.Vordachlänge = newValue
    9. case DachneigungTextField:
    10. roofGeometry.Dachneigung = newValue
    11. default:
    12. print("shoulf not happen")
    13. }
    14. FirsthöheTextField.text = String(roofGeometry.FirsthöheBerechnet)
    15. okFußpfetteTextField.text = String(roofGeometry.okFußpfetteDN)
    16. okFirstpfetteTextField.text = String(roofGeometry.okFirstpfetteDN)
    17. }
    18. else if(myTextField.text == "Grdmaß-Firsthö-Traufhö-Vordach")
    19. {
    20. switch sender {
    21. case GrundmaßTextField:
    22. roofGeometry.Grundmaß = newValue
    23. case TraufhöheTextField:
    24. roofGeometry.Traufhöhe = newValue
    25. case VordachlängeTextField:
    26. roofGeometry.Vordachlänge = newValue
    27. case FirsthöheTextField:
    28. roofGeometry.Firsthöhe = newValue
    29. default:
    30. print("shoulf not happen")
    31. }
    32. DachneigungTextField.text = String(roofGeometry.DachneigungBerechnet)
    33. okFußpfetteTextField.text = String(roofGeometry.okFußpfetteFH)
    34. okFirstpfetteTextField.text = String(roofGeometry.okFirstpfetteFH)
    35. }
    Alles anzeigen
    ich lese damit zwar das Textfeld aus und nicht welche Zeile im Picker gerade aktiv ist aber es geht. Ach und in der roofGeometry hab ich dann halt die entsprechenden Berechnungen zur jeweiligen Zeile des Pickers abgelegt und siehe da ich hab kein Konflikt mehr.
  • matze511 schrieb:

    Das mit dem Picker hab ich hier schonmal als Thema gehabt aber bin da nicht so recht schlau draus geworden. ?(
    laden der daten aus anderem view

    Aber das hat @Michael da doch in dem von Dir verlinkten Beitrag bestens erklärt:

    Michael schrieb:

    Der Methode pickerView(_:didSelectRow:inComponent:) wird die die gerade ausgewählte Zeile als Parameter übergeben. Den Wert merkst du dir in einer Instanzvariablen und dann weißt du in deiner Action Methode über diese Instanzvariable, welche Zeile gerade im PickerView ausgewählt ist.

    Dein ViewController bekommt eine Property var selectedPickerRow: Int. In pickerView(_:didSelectRow:inComponent:) weißt Du ihr den Wert der zu didSelectRow gehörenden Variable zu und später, wenn Du den Wert brauchst, kannst Du auf die Property selectedPickerRow Deines ViewControllers zurückgreifen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von torquato ()

  • tsunamix schrieb:

    Ich vermute, Dir ist nicht ganz klar was static in Swift heißt. Mit static werden in Swift properties und Funktionen der Klasse deklariert, nicht Properties oder Funktionen der Instanzen. Die Klasse, sowie die Properties einer Klasse existieren nur einmal - threadübergreifend.
    Das ist mir bekannt. In dem Beitrag, auf dem ich geantwortet habe, ging es um JEDE Property und JEDEN Code.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?