Optional<AnyObject> Typ bekommen

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

  • Optional<AnyObject> Typ bekommen

    hallo meine lieben,
    ich bekomme beim auslesen einer Datei den wert Optional(1) in der variable datei1
    Mache ich dann

    Quellcode

    1. print(mirror(reflecting: test))


    erhalte ich "Optional<AnyObject>". Wenn ich hingegen direkt

    Quellcode

    1. print(mirror(reflecting: Optional(1)))
    mache, erhalte ich "Optional<Int>". Da der ausgelesene Wert sowohl, Strings, Zahlen und wahrheitswerte sein kann, weiß ich nicht, wie ich test nun auf die verschiedenen fälle überprüfen kann

    danke ^^
  • conditional Casting mit as?.

    Beispiel:

    C-Quellcode

    1. var array = [Any]()
    2. array.append("foo")
    3. array.append(1)
    4. for x in array {
    5. if let value = x as? String {
    6. print(value + "bar")
    7. }
    8. else if let value = x as? Int {
    9. print(value * 5)
    10. }
    11. }
    Alles anzeigen
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • danke dir, das funktioniert schon besser, einziges problem sind jetzt noch zahlen und wahrheitswerte. Je nach dem, welches vorher in der if-Bedingung auftaucht, wird es als zahl oder bool markiert.
    also wenn ich halt x = 54 oder x = 1 hab, und bool früher als int in der if-abfrage steht, bekomme ich true zurück.
    andersrum ist es dann halt genau, nur andersrum.

    wie kann man das jetzt noch besser "filtern"?
    ?(
  • O.g. Beispiel um Boolean-Werte ergänzt:

    C-Quellcode

    1. var array = [Any]()
    2. array.append("foo")
    3. array.append(false)
    4. array.append(1)
    5. for x in array {
    6. if let value = x as? String {
    7. print(value + "bar")
    8. }
    9. else if let value = x as? Bool {
    10. print(value)
    11. }
    12. else if let value = x as? Int {
    13. print(value * 5)
    14. }
    15. }
    Alles anzeigen

    Funktioniert problemlos und ergibt folgenden Output:

    Quellcode

    1. foobar
    2. false
    3. 5
    Das Problem liegt also schon vorher an Deiner Datei, bzw. wie die geparsed wird. Was machst Du denn, um die Datei auszulesen?
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • AppleDeveloper schrieb:

    Ich habe keine große Ahnung von Swift aber wenn die Zahl jetzt 1 oder 0 heißt wird es dann nicht als Bool interpretiert?

    In Swift selbst sind Boolean- und Intereger-Werte vollkommen unterschiedliche Datentypen. Die können noch nicht mal zwangsweise hin- und hergecastet werden!

    Trotzdem. Ich vermute auch, daß beim Auslesen der Datei irgendetwas in der Richtung passiert...
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • torquato schrieb:

    [...]


    Das Problem liegt also schon vorher an Deiner Datei, bzw. wie die geparsed wird. Was machst Du denn, um die Datei auszulesen?

    torquato schrieb:

    [...]

    Trotzdem. Ich vermute auch, daß beim Auslesen der Datei irgendetwas in der Richtung passiert...
    Ja, richtig vermutet, also ich lese ein plist-datei aus und speichere sie in einem dic. Wenn ich das ausgelesene Objekt nun x zuweise, wird x zu einem Optional und dem ausgelesenen Wert, also zum Beispiel Optional(5). In diesem Fall greift dann dein code auch nicht, weil ein Downcast stattfinden muss (steht so bei Xcode), nach dem x muss dafür ein Ausrufezeichen stehen, also sowas wie "value = x! as? Bool".

    Jetzt habe ich quasi folgendes

    Quellcode

    1. let x = dict.ObjectForKey("test")
    2. if let value = x! as? String {
    3. print(value + "bar")
    4. }
    5. else if let value = x! as? Bool {
    6. print(value)
    7. }
    8. else if let value = x! as? Int {
    9. print(value * 5)
    10. }
    Wird aus "test" ein String ausgelesen, klappt alles. Wird aber eine zahl ausgelesen, wird, wenn sie größer als 0 ist, true zurückgegeben. Bei einem bool auch (je nach dem, ob true/false). Steht zuerst die Überprüfung aus eine zahl in der reihe, wird bei einer zahl logischerweise die zahl ausgegeben, bei einem boolean aber auch (also entweder 0 oder 1).

    Der code wird übrigens benötigt, um falsche Modifikationen zu erkennen und einen Programmfehler zu vermeiden.
  • Erstmal eine Bemerkung nicht direkt zu Deinem Problem.
    Explicitly unwrapped optionals, also die, besonders bei Anfängern immer sehr beliebten Ausrufezeichen ( ;) ), sind idR zu 99 Prozent falscher Code, mit dem man sagt, daß man sich ins Knie schießen will. Es gibt nur ganz wenige vereinzelte Fälle, in denen man die benutzen sollte.

    Meide in Swift das ! wie der Teufel das Weihwasser!

    Dein Code

    Quellcode

    1. let x = dict.ObjectForKey("test")
    2. if let value = x! as? String {
    3. print(value + "bar")
    4. }
    sollte in Swift folgendermaßen aussehen:

    Quellcode

    1. if let x = dict["test"] {
    2. if let value = x as? String {
    3. print(value + "bar")
    4. }

    In Swift greift man üblicherweise auch nicht über objectForKey auf die Elemente eines Dictionarys zu.^^

    Ich vermute, daß Du via NSProperyListSerialization die plist ausliest. In Cocoa werden da Boolean-Werte als NSNumber übergeben. Ich verfmute, daß da bei Dir der Hase im Pfeffer begraben liegt. Da kann ich spontan keine Lösung bieten. Da muß jemand anderes einschreiten.
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • torquato schrieb:

    Erstmal eine Bemerkung nicht direkt zu Deinem Problem.
    Explicitly unwrapped optionals, also die, besonders bei Anfängern immer sehr beliebten Ausrufezeichen ( ;) ), sind idR zu 99 Prozent falscher Code, mit dem man sagt, daß man sich ins Knie schießen will. Es gibt nur ganz wenige vereinzelte Fälle, in denen man die benutzen sollte.

    Meide in Swift das ! wie der Teufel das Weihwasser!

    [...]

    Quellcode

    1. if let x = dict["test"] {
    2. if let value = x as? String {
    3. print(value + "bar")
    4. }
    In Swift greift man üblicherweise auch nicht über objectForKey auf die Elemente eines Dictionarys zu.^^

    [...]
    Also, bei vielen meiner Funktionen schlägt mir Xcode im return das Ausrufezeichen vor, wie löse ich das denn jetzt "richtig"?

    Okay, das wusste ich nicht, gibt es dafür einen speziellen Grund, dass man zum Auslesen nicht objectForKey nimmt?
  • prettygirl schrieb:

    Also, bei vielen meiner Funktionen schlägt mir Xcode im return das Ausrufezeichen vor, wie löse ich das denn jetzt "richtig"?

    Man sollte nicht alles glauben, was Xcode einem sagt. :D

    Kann ich so spontan im 'Blindflug' nicht sagen. Ich vermute, daß Du das Prinzip Optionals in Swift noch nicht so ganz verstehst und deshalb in solche Compilermeldungen gerätst.

    Poste doch einfach mal so einen Fall. Vielleicht kann ich (oder jemand anders) dann was dazu sagen.

    prettygirl schrieb:

    Okay, das wusste ich nicht, gibt es dafür einen speziellen Grund, dass man zum Auslesen nicht objectForKey nimmt?

    Du kanst natürlich auch objectForKey nehmen. Das ist keine Frage.

    objectForKey ist eine Methode von NSDictionary. Das ist Foundation API aus Objective-C heraus geboren. Swift hat von Haus aus den Typ Dictionary (ohne NS) eingebaut. Dieser Swift-Typ hat diese Methode objectForKey eigentlich gar nicht, sondern greift von Haus aus über Subscripts auf die Elemente zu, einfach der von der Sprachsyntax her vorgesehene Weg in Swift.

    Mischt man beides, wird zwischen dem Foundation NSDictionary und dem Swift Dictionary unter der Haube eine Brücke gebaut, so daß auch ein Swift-Dictionary plötzlich damit umgehen kann. Davon kriegt man in der Regel gar nichts mit und es ist auch nicht weiter schlimm.

    Da Du in Swift schreibst, wollte ich lediglich darauf hinweisen, daß Swift da eigene Möglichkeite hat, die man normalerweise nimmt, statt auf die Foundation API zurückzugreifen.

    Aber, wie gesagt: objectForKey ist vollkommen legitim.
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • prettygirl schrieb:

    gibt es dafür einen speziellen Grund, dass man zum Auslesen nicht objectForKey nimmt?

    Noch eine launige Randbemerkung dazu.

    In Swift 3 (geplant für Ende 2016. Ich gehe von Anfang 2017 aus) wird es in Zukunft dict.object(forKey: "test") heißen anstatt dict.objectForKey("test"). Da hat ein ganzer Kindergarten von hochintellinenten Programmierern monatelang drüber diskutiert, und ich habe bis heute nicht verstanden, was die gestochen hat oder was die geraucht haben....

    Mit dict["test"] ist man einfach heute schon auf der sicheren Seite. ;)
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • torquato schrieb:

    objectForKey ist eine Methode von NSDictionary. Das ist Foundation API aus Objective-C heraus geboren.
    Nur als Ergänzung: auch in Objective-C kann man schon eine Weile per Subscript auf die Inhalte eines NSDictionary zugreifen.

    torquato schrieb:

    Swift hat von Haus aus den Typ Dictionary (ohne NS) eingebaut. Dieser Swift-Typ hat diese Methode objectForKey eigentlich gar nicht, sondern greift von Haus aus über Subscripts auf die Elemente zu, einfach der von der Sprachsyntax her vorgesehene Weg in Swift.
    Nur wissen wir gar nicht, ob wir es überhaupt mit einem Swift Dictionary zu tun haben oder ob das Einlesen der Plist ein NSDictionary liefert.
  • Michael schrieb:

    torquato schrieb:

    objectForKey ist eine Methode von NSDictionary. Das ist Foundation API aus Objective-C heraus geboren.
    Nur als Ergänzung: auch in Objective-C kann man schon eine Weile per Subscript auf die Inhalte eines NSDictionary zugreifen.

    Ja. Stimmt natürlich.^^
    Ich habe sehr (seeeehr!) lange nicht mehr was in Objective-C gemacht. :)
    Eine frühere Änderung in Objective-C hat also schon mal ein Feature in Swift vorweggenommen.

    Michael schrieb:

    torquato schrieb:

    Swift hat von Haus aus den Typ Dictionary (ohne NS) eingebaut. Dieser Swift-Typ hat diese Methode objectForKey eigentlich gar nicht, sondern greift von Haus aus über Subscripts auf die Elemente zu, einfach der von der Sprachsyntax her vorgesehene Weg in Swift.
    Nur wissen wir gar nicht, ob wir es überhaupt mit einem Swift Dictionary zu tun haben oder ob das Einlesen der Plist ein NSDictionary liefert.

    Wenn, wie ich vermute, die plist mit NSProperyListSerialization ausgelesen wird, kommt bestimmt ein NSDictionary raus. Das ist aber nicht der Punkt. Wenn man sich innerhalb einer Sprache befindet, sollte man doch üblicherweise auch, nach Möglichkeit innerhab der Sprachsyntax bleiben, oder nicht?
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • Danke, habe es jetzt das objectForKey ersetzt :)

    torquato schrieb:

    prettygirl schrieb:

    Also, bei vielen meiner Funktionen schlägt mir Xcode im return das Ausrufezeichen vor, wie löse ich das denn jetzt "richtig"?
    Man sollte nicht alles glauben, was Xcode einem sagt. :D

    Kann ich so spontan im 'Blindflug' nicht sagen. Ich vermute, daß Du das Prinzip Optionals in Swift noch nicht so ganz verstehst und deshalb in solche Compilermeldungen gerätst.

    Poste doch einfach mal so einen Fall. Vielleicht kann ich (oder jemand anders) dann was dazu sagen.


    [...]
    Ganz allgemein gesagt, als Beispiel ...

    Quellcode

    1. func test(test: Int) -> Int {
    2. var newtest: Int?
    3. if (test >= 0) {
    4. newtest = test
    5. } else {
    6. newtest = 1
    7. }
    8. return newtest!
    9. }
  • Abgesehen, von dem Shortcut den @gritsch genannt hat...

    Wenn eine Variable 'newtest' gar nicht nil sein kann und soll, dann deklariert man sie erst gar nicht als Optional. Einfach statt var newtest: Int? var newtest: Int und man erspart sich die Frage- und Ausrufezeichen.

    Ich vermute mal, Du hast irgendwo im Netz in einem Tutorial oder so etwas wie var newtest: Int? gesehen und verwendest das jetzt, hast aber nicht so recht verstanden, was das Fragezeichen eigentlich bezwecken soll... *schulterzuck*
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • Noch eine kleine Lappalie, die ich, glaube ich, hier im Forum schon mal an anderer Stelle erwähnt habe.

    prettygirl schrieb:


    Quellcode

    1. if (test >= 0) {

    In C und Derivaten sind mW die runden Klammern bei solchen if-Abfragen zwingend. In Swift kann, ja sollte man sogar besser auf diese Klammern verzichten.

    In der Swift-'community' besteht der überwiegende Konsens, daß solche sprachlich nicht notwendigen Klammern möglichst nicht gesetzt werden. Sie erhöhen nur das Buchstaben-Grundrauschen im Code, haben aber keine eigene Funktion...
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • torquato schrieb:

    Noch eine kleine Lappalie, die ich, glaube ich, hier im Forum schon mal an anderer Stelle erwähnt habe.

    prettygirl schrieb:

    Quellcode

    1. if (test >= 0) {
    In C und Derivaten sind mW die runden Klammern bei solchen if-Abfragen zwingend. In Swift kann, ja sollte man sogar besser auf diese Klammern verzichten.

    In der Swift-'community' besteht der überwiegende Konsens, daß solche sprachlich nicht notwendigen Klammern möglichst nicht gesetzt werden. Sie erhöhen nur das Buchstaben-Grundrauschen im Code, haben aber keine eigene Funktion...

    Wenn das wirklich so sein sollte dann spinnen die doch komplett.
    Auch wenn es nicht nötig ist, hilft es doch ungemein den code verständlicher zu machen und das ist das ALLERWICHTIGSTE!