¿Por qué puedo lanzar a NSManagedObject pero no al tipo de mi entidad?

Estoy usando el código repetitivo Swift para Core Data en un proyecto nuevo. Mi archivo .xcdatamodeld tiene una única entidad definida ( Task ) con un solo atributo ( name ).

Tengo un archivo Task.swift que se ve así:

 import CoreData class Task: NSManagedObject { @NSManaged var name: String } 

Cuando ejecuto esto, funciona:

 var firstTask = NSEntityDescription.insertNewObjectForEntityForName("Task", inManagedObjectContext: managedObjectContext) as NSManagedObject firstTask.setPrimitiveValue("File my TPS reports", forKey: "name") var error: NSError? managedObjectContext.save(&error) 

Incluso puedo acceder a la base de datos SQLite utilizada por el simulador de iOS y confirmar que se haya agregado la fila.

Sin embargo, cuando ejecuto exactamente el mismo código que el anterior, pero as Task lugar de as NSManagedObject , as NSManagedObject un error con el mensaje de error Thread 1: EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0) , asociado con la línea var firstTask … Si continúo la ejecución, obtengo EXC_BAD_ACCESS y 0 misaligned_stack_error_ EXC_BAD_ACCESS en la parte superior del subproceso 1 cada vez que lo adelanto.

¿Por qué este elenco podría llevar a todo esto?

Asegúrese de que su campo de nombre de clase sea en realidad Module .Task, donde Module es el nombre de su aplicación. Las clases de CoreData en Swift son espacios de nombres. En este momento, su objeto se está sacando del contexto como un NSManagedObject, no como una Tarea, por lo que el as-cast está fallando.

Esto incluso se frustra si pruebas todas las sugerencias anteriores y ninguna de ellas funciona para mí.

Entonces esto es lo que funciona para mí.

1- Seleccione su archivo xcdatamodeld

2- Asegúrese de que todas sus entidades no tengan ningún Módulo en el “Inspector del modelo de datos”, si ve “Modelo: Módulo de producto actual”, límpielo para que se vea como la imagen adjunta.

3- Elimina tu aplicación para borrar los datos principales

4- Si aún no funciona, elimine sus entidades y vuelva a generarlas.

enter image description here

Necesita modificar su archivo Task.swift. Agregar @objc (Tarea) como a continuación

 import CoreData @objc(Task) class Task: NSManagedObject { @NSManaged var name: String } 

Creo que esto es un error si su proyecto no contiene ningún código objective c. Sin embargo, debe agregar esa línea hasta que esto se solucione.

Lo aprendí de aquí

Video de Youtube a las 11:45

Supongo que solo cambiar el campo de clase en .xcdatamodel ya no funciona porque todavía tengo la siguiente excepción: error fatal: uso del inicializador no implementado ‘init (entidad: insertIntoManagedObjectContext :)’ para la clase

Entonces, ingresé este código en mi clase personalizada:

  init(entity: NSEntityDescription!, insertIntoManagedObjectContext context: NSManagedObjectContext!) { super.init(entity: entity, insertIntoManagedObjectContext: context) } 

De repente, funcionó! El NSManagedObject ahora se puede convertir a mi clase personalizada. Realmente no puedo entender por qué esta es la solución, pero funciona 🙂

Una actualización para @Ben Gottlieb respuesta bajo XCode 7.1 y Swift 2.0

  1. agrega @objc a tu clase. Ver la respuesta de Owen Zhao. Lo siguiente es un ejemplo:
 @objc class ImageRecordMO: NSManagedObject{ 
  1. Abra su archivo .xcdatamodled.

  2. Seleccione su entidad y haga clic en el inspector del modelo de datos en el panel derecho.

  3. Ingrese el nombre de la clase, vea la figura a continuación

  4. Seleccione su módulo para ser Módulo de Producto Actual, vea la figura a continuación.

enter image description here

Xcode 7 + Swift 2

Person.swift

 @objc(Person) class Person: NSManagedObject { } 

Modelo de datos

enter image description here

Entonces simplemente llame

 let person = NSEntityDescription.insertNewObjectForEntityForName("Person", inManagedObjectContext: self.managedObjectContext) as! Person 

Tuve que agregar @objc () y establecer la clase en la interfaz de coredata . En la ventana derecha de CoreData, en el área Entidad, hay un cuadro de texto Nombre y Clase. La clase no debe ser MSManagedObject sino su clase . ¡Creé un ejemplo de trabajo simple !

Me he encontrado con este problema en los últimos días y, curiosamente, la solución que funcionó para mí fue una variante de la sugerida anteriormente.

Agregué la statement @objc a las subclases generadas, pero eliminé cualquier prefijo del espacio de nombres en el nombre de la clase en el modelo de objetos (tenía un prefijo predeterminado de “PRODUCT_MODULE_NAME” después de que se generaron las subclases). Eso funciono.