2 Stimmen

Warum erhalte ich "Swift Dynamic Cast Failed" ?? :/

Ich habe mich gefragt, ob mir jemand das Konzept des "Cast" oder "Casting" bezüglich Programmierung erklären und mir auch bei dem Problem helfen könnte, das ich beim Ausführen dieses Codes bekomme:

import UIKit
import CoreData

class vcMain: UIViewController {

    @IBOutlet var txtUsername: UITextField!
    @IBOutlet var txtPassword: UITextField!

    @IBAction func btnSave(){
        //println("Save button pressed \(txtUsername.text)")//Fügt den geschriebenen Text in die Konsole hinzu
        var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
        var context:NSManagedObjectContext = appDel.managedObjectContext

        var newUser = NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: context) as NSManagedObjectContext
        newUser.setValue("Test Username", forKey: "username")
        newUser.setValue("Test Password", forKey: "password")

        context.save(nil)

        println(newUser)
        println("Object Saved.")

    }

    @IBAction func btnLoad(){
        //println("Load button pressed \(txtPassword.text)")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Führe nach dem Laden der Ansicht zusätzliche Einrichtungen durch.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Entsorge der nicht mehr benötigten Ressourcen.
    }
}

Ich folge einem Tutorial auf YouTube, kann aber nicht herausfinden, warum es bei mir nicht funktioniert!

7voto

Jack Lawrence Punkte 10554

Diese Zeile sieht falsch aus:

var newUser = NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: context) as NSManagedObjectContext

Du konvertierst zu einem NSManagedObjectContext, wenn du wahrscheinlich zu einem NSManagedObject konvertieren wolltest. Die Zeile sollte also lauten:

var newUser = NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: context) as NSManagedObject

0 Stimmen

Können Sie mir bitte bei diesem Problem helfen? : stackoverflow.com/questions/28042105/…

2voto

Ethan Punkte 1567

Ich stimme der Antwort von Jack Lawrence zu.

Wir betrachten die Funktion NSEntityDescription.insertNewObjectForEntityForName("Benutzer", inManagedObjectContext: context), die laut Dokumentation einen ObjC-Typ, id, zurückgibt, der sozusagen in Swift als AnyObject übersetzt wird. Das heißt, der Computer weiß nicht, was es ist, aber wir schon, weil wir die Dokumentation gelesen haben:

insertNewObjectForEntityForName:inManagedObjectContext: Erstellt, konfiguriert und gibt eine Instanz der Klasse für die Entität mit einem gegebenen Namen zurück.

Rückgabewert Eine neue, autoreleased, vollständig konfigurierte Instanz der Klasse für die Entität mit dem Namen entityName. Die Instanz hat ihre Entitätsbeschreibung festgelegt und wird in den Kontext eingefügt.

Wie auch immer, Sie können sicher davon ausgehen, dass es einen Typ NSManagedObject oder eine Unterklasse davon zurückgibt.

Nun zum Casting:

Das meiste davon stammt aus dem Swift iBook. Sie wissen bereits, dass das Type Casting / Downcasting in Swift mit dem as-Operator erfolgt. Da Downcasting fehlschlagen kann, gibt es den Typ-Cast-Operator in zwei Formen. 1) Erzwungenes as und 2) Optionales as?

Der Unterschied besteht im Wesentlichen darin, dass Sie as? verwenden, wenn Sie nicht sicher sind, ob das Downcasting erfolgreich ist, und as, wenn Sie davon überzeugt sind, dass es erfolgreich sein wird. Hier ist ein Beispiel, bei dem ich ein Array namens Vehicles habe, das zwei verschiedene Klassen, Car und Truck, enthält, von denen es 5 Autos und 2 Lastwagen gibt.

var carCount = 0
var truckCount = 0
for vehicle in vehicles{
    if let car = car as? Car
    {
        carCount++
    } else
    if let truck = truck as? Truck
    {
        truckCount++
    }
}

Am Ende sind meine Zähler korrekt und es wurde keine Fehlermeldung generiert. Aber der Versuch, auf eines der Elemente von vehicles zuzugreifen, wie vehicles[i] as Car, wäre gefährlich, weil es sich um einen Lastwagen handeln könnte und Sie mit Gewalt sagen würden, dass es ein Auto ist. Laufzeitfehler!

Wie auch immer, ich hoffe, das erklärt es ein wenig. Wenn nicht, sehen Sie sich das Kapitel über Type Casting im Swift iBook auf Seite 391 an.

0voto

user2294382 Punkte 851

Für alle anderen da draußen mit einem ähnlichen Problem. Es gibt hier einen kleinen Trick.

Wenn Sie versuchen, eine benutzerdefinierte NSManagedObject-Unterklasse mit der Methode NSEntityDescription.insertNewObjectForEntityForName(Entity, inManagedObjectContext: context) zu generieren, stellen Sie sicher, dass der Swift-Klasse das @objc() -Header vor der Klasse hinzugefügt wurde. Andernfalls werden Sie auch ein dynamisches Klassen-Cast-Fehler erleben.

0 Stimmen

Sie müssen hier das Attribut @objc nicht verwenden. Siehe "Implementieren von Core Data Managed Object Subklassen" in developer.apple.com/library/prerelease/ios/documentation/Swi‌​ft/…

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X