multithreading - que - CoreData: advertencia: no se puede cargar la clase llamada
proceso multithread (11)
Estoy duplicando una aplicación existente de Show de TV de Objective-C a una nueva versión de Swift usando Xcode 6.1 y estoy teniendo algunos problemas con CoreData.
Creé un modelo de 4 entidades, creé su subclase NSManagedObject (en Swift) y todos los archivos tienen los objetivos de aplicación adecuados establecidos (para ''Compilar fuentes'').
Todavía recibo este error cada vez que intento insertar una nueva entidad:
CoreData: advertencia: no se puede cargar la clase llamada ''Shows'' para la entidad ''Shows''. Clase no encontrada, utilizando NSManagedObject predeterminado en su lugar.
Algunos comentarios:
Al guardar en Core Data, uso el modo de contexto principal-secundario para permitir el enrutamiento de fondo. Lo hago configurando ManagedObjectContext usando:
lazy var managedObjectContext: NSManagedObjectContext? = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
let coordinator = self.persistentStoreCoordinator
if coordinator == nil {
return nil
}
var managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
y guardando datos usando:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
var context = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
context.parentContext = self.managedObjectContext!
...rest of core data saving code here...
})
Actualización de SWIFT 2 / XCODE 7:
Este problema (ver también mi comentario del 3 de abril sobre esta respuesta) se resuelve en las versiones beta de Swift 2 y XCode 7 de Apple. Entonces, en realidad, ahora no necesita
@objc(myEntity)
en Swift como lo responde Mundi ni usa "MyAppName.
" Antes de su nombre de Clase. Dejará de funcionar. ¡Así que elimínelos, simplemente coloque el nombre deClass
en Archivo y seleccioneCurrent Working Module
como Módulo y ¡aplausos!
Pero para aquellos que usan @objc(myEntity)
en Swift (como yo), puedes usar esta otra solución que funciona sin problemas.
En la clase correcta de xcdatamodel, debería verse así:
Aqui tienes. Module.Class
es el patrón para CoreData en Swift y XCode 6. También necesitará el mismo procedimiento cuando utilice la clase de política personalizada en Model Policy u otras cosas de CoreData. Una nota: en imagen, The Name and Class debe ser Car y MyAppName.Car (o el nombre de su entidad). Aquí, el User
es un error tipográfico.
Al usar Xcode 7 y puramente Swift, en realidad tuve que eliminar @objc(MyClass)
de mi subclase NSManagedObject
generada NSManagedObject
(generada desde Editor > Crear subclase NSManagedObject ... ).
Cambiar el nombre de la clase de entidad en el editor del modelo de datos para que se corresponda con la clase en cuestión y agregar @objc(NameOfClass)
al archivo de cada NSManagedObject justo encima de la declaración de clase resolvió este problema durante la prueba unitaria.
Con xCode 7 y la versión Swift 2.0, no necesita agregar @objc (NameOfClass), simplemente cambie la configuración de la entidad en la pestaña "Mostrar el Inspector del Modelo de Datos" como se muestra a continuación:
Nombre - "Nombre de su entidad"
Clase - "Su nombre de entidad"
Módulo - "Módulo de producto actual"
El código para el archivo de la clase Entity será similar (en mi código Entity is Family) -
import UIKit
import CoreData
class Family: NSManagedObject {
@NSManaged var member : AnyObject
}
Este ejemplo funciona bien en mi aplicación con xCode 7.0 + swift 2.0
En Xcode 6.1.1 no necesita agregar el atributo @objc ya que la entidad base es un subconjunto de una clase objc (NSManagedObject) (vea Compatibilidad de tipo Swift . En CoreData se requiere el nombre completo de Module.Class. Tenga en cuenta el Módulo nombre es lo que se establece en Configuración de compilación -> Envasado -> Nombre del módulo del producto. De forma predeterminada, está configurado en $ (NOMBRE_DEL_PRODUCTO: c99extidentificador) que será el nombre del Destino .
En Xcode 7 beta 2 (y creo 1), en la configuración del modelo, un nuevo objeto gestionado de tipo File
se configura en el Módulo Módulo de Current Product Module
y la clase del objeto se muestra en la configuración como .File
.
Eliminar la configuración del módulo para que esté en blanco, o eliminar el punto final para que el nombre de la clase en la configuración sea solo File
son acciones equivalentes, ya que cada una causa el otro cambio. Guardar esta configuración eliminará el error descrito.
Esta advertencia es una de las peculiaridades con las que tenemos que lidiar mientras se resuelven los detalles de la implementación de Swift. La advertencia se produce de forma espuria, es decir, su configuración podría funcionar incluso si no sigue los pasos que se detallan a continuación.
Pude deshacerme de él en la mayoría de los casos al asegurarme de que la clase esté configurada correctamente en el editor de modelos . A diferencia de muchas otras publicaciones de SOF (incluidas las respuestas a esta pregunta), la sugerencia de incluir el nombre del módulo (como MyApp.Shows
) no me ha ayudado.
Asegúrese de verificar estos tres elementos:
1.
Versión que funciona hasta Xcode 7 beta 3
Tenga en cuenta que corregí el nombre de su entidad al singular más apropiado.
Versión que funciona para Swift 2.0 en Xcode 7.1
(Debería funcionar para Xcode 7 beta 4 y superior)
¡Debe eliminar el texto "Módulo de producto actual" en el Módulo!
2.
También debe seguir la recomendación frecuente de incluir
@objc(Show)
justo arriba de tu clase.
Nota : Si está utilizando Xcode 7 beta 4 o posterior, este paso es opcional.
3.
También asegúrese de convertir el objeto gestionado creado a la clase adecuada, ya que el valor predeterminado sería simplemente NSManagedObject
.
var newShow = NSEntityDescription.insertNewObjectForEntityForName("Show",
inManagedObjectContext: context) as Show
Lo que funcionó para mí (Xcode 7.4, Swift) está cambiando el nombre de la clase a <my actual class name>.<entity name>
en el inspector de <my actual class name>.<entity name>
en el cuadro "Clase".
Mi iniciador de la subclase Objeto gestionado se ve así:
convenience init(<properties to init>) {
let entityDescr = NSEntityDescription.entityForName("<entity class name>", inManagedObjectContext: <managed context>)
self.init(entity: entityDescr!, insertIntoManagedObjectContext: <managed context>)}
//init properties here
No olvide reemplazar PRODUCT_MODULE_NAME
con el nombre de su módulo de producto.
Cuando se crea una entidad nueva, debe dirigirse al Inspector del modelo de datos (última pestaña) y reemplazar PRODUCT_MODULE_NAME
con su nombre de módulo, o se producirá un error de class not found
al crear el coordinador de tienda persistente.
También debe usar (al menos con Xcode 6.3.2) Module.Class al realizar su lanzamiento, por ejemplo: Asumiendo que su módulo (es decir, el nombre del producto) es Food y su clase es Fruit
let myEntity = NSEntityDescription.entityForName("Fruit", inManagedObjectContext: managedContext)
let fruit = NSManagedObject(entity: myEntity!, insertIntoManagedObjectContext:managedContext) as! Food.Fruit
Resumen:
- Incluya el nombre del módulo al definir la entidad en el Editor de modelo de datos (Nombre: Fruta, Clase: Comida.Fruta)
- Al acceder a la entidad en el código (es decir, SWIFT), ejecútelo con Module.class (por ejemplo, Food.Fruit)
También encontré un problema similar, siga estos pasos para resolver: