J'utilise le Swift standard pour les données de base dans un nouveau projet. Mon fichier .xcdatamodeld
A une seule entité définie (Task
) avec un seul attribut (name
).
J'ai un fichier Task.Swift
Qui ressemble à ceci:
import CoreData
class Task: NSManagedObject {
@NSManaged var name: String
}
Lorsque je lance cela, cela fonctionne:
var firstTask = NSEntityDescription.insertNewObjectForEntityForName("Task",
inManagedObjectContext: managedObjectContext) as NSManagedObject
firstTask.setPrimitiveValue("File my TPS reports", forKey: "name")
var error: NSError?
managedObjectContext.save(&error)
Je peux même aller dans la base de données SQLite utilisée par le simulateur iOS et confirmer que la ligne a été ajoutée.
Cependant, lorsque j'exécute exactement le même code que ci-dessus mais avec as Task
Au lieu de as NSManagedObject
, J'obtiens un plantage avec le message d'erreur Thread 1: EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
, associé au var firstTask
… Ligne. Si je continue l'exécution, j'obtiens EXC_BAD_ACCESS
Et 0 misaligned_stack_error_
En haut du fil 1 chaque fois que je le fais avancer.
Pourquoi cette distribution pourrait-elle mener à tout cela?
Assurez-vous que le champ Nom de votre classe est bien Module. Tâche, où Module est le nom de votre application. Les classes CoreData dans Swift sont des espaces de noms. À l'heure actuelle, votre objet est extrait du contexte en tant que NSManagedObject, pas en tant que tâche, donc la conversion échoue.
C'est même frustré si vous avez essayé toutes les suggestions ci-dessus et qu'aucune d'entre elles ne travaille pour moi !!
Voilà donc ce qui fonctionne pour moi.
1- Sélectionnez votre fichier xcdatamodeld
2- Assurez-vous que toutes vos entités n'ont pas de module dans le "Data Model Inspector", si vous voyez "Model: Current Product Module" ... effacez-le pour qu'il ressemble à l'image jointe.
3- Supprimez votre application pour effacer les données de base
4- Si cela ne fonctionne toujours pas, supprimez vos entités et régénérez-les.
Vous devez modifier votre fichier Task.Swift. Ajout de @objc (tâche) comme ci-dessous
import CoreData
@objc(Task)
class Task: NSManagedObject {
@NSManaged var name: String
}
Je pense que c'est un bug si votre projet ne contient pas de codes objective-c. Cependant, vous devez ajouter cette ligne jusqu'à ce que cela soit résolu.
Je l'ai appris d'ici.
Je suppose que seul le changement du champ de classe dans le .xcdatamodel ne fonctionne plus car j'ai toujours l'exception suivante: erreur fatale: utilisation de l'initialiseur non implémenté 'init (entity: insertIntoManagedObjectContext :)' pour la classe
J'ai donc entré ce code dans ma classe personnalisée:
init(entity: NSEntityDescription!,
insertIntoManagedObjectContext context: NSManagedObjectContext!) {
super.init(entity: entity, insertIntoManagedObjectContext: context)
}
Du coup, ça a marché! NSManagedObject peut désormais être converti dans ma classe personnalisée. Je ne comprends pas vraiment pourquoi c'est la solution, mais ça marche :)
Une mise à jour pour @Ben Gottlieb réponse sous XCode 7.1 et Swift 2.0
@objc class ImageRecordMO: NSManagedObject{
Ouvrez votre fichier .xcdatamodled.
Sélectionnez votre entité et cliquez sur l'inspecteur de modèle de données dans le panneau de droite.
Entrez le nom de la classe, voir la figure ci-dessous
Sélectionnez votre module comme module de produit actuel, voir la figure ci-dessous.
J'ai dû ajouter @objc () et définir la classe dans l'interface coredata . Dans la fenêtre droite de CoreData, dans la zone Entité, il y a la zone de texte Nom et Classe. La classe ne doit pas être MSManagedObject mais plutôt votre classe . J'ai créé un exemple de travail simple !
J'ai rencontré ce problème au cours des derniers jours et, étrangement, la solution qui a fonctionné pour moi était une variante de celle suggérée ci-dessus.
J'ai ajouté la déclaration @objc aux sous-classes générées, mais j'ai supprimé tout préfixe d'espace de noms dans le nom de classe dans le modèle d'objet (il avait un préfixe par défaut "PRODUCT_MODULE_NAME." Après la génération des sous-classes). Ça a marché.