tutorial persistencia existing example español datos data con ios objective-c core-data swift

ios - persistencia - Swift+CoreData: no se puede establecer un Bool en la subclase NSManagedObject-¿Error?



persistencia de datos en swift 4 (6)

Tengo un pequeño problema extraño que parece que no puedo resolver, tengo una entidad simple con una subclase NSManagedObject personalizada:

@objc(EntityTest) class EntityTest: NSManagedObject { @NSManaged var crDate: NSDate @NSManaged var name: String @NSManaged var completed: Bool @NSManaged var completedOn: NSDate }

Este es el problema, puedo crear la multa del objeto y establecer todos los valores y almacenarlos en una matriz. Sin embargo, más tarde, cuando intento recuperar el mismo objeto, puedo establecer todos los valores EXCEPTO el campo "completado". Recibo un error en tiempo de ejecución que dice "EXC_BAD_ACCESS", puedo leer el valor, pero no puedo establecerlo.

El depurador apunta a:

0x32d40ae: je 0x32d4110 ; objc_msgSend + 108 0x32d40b0: movl (%eax), %edx

Tal vez algunos problemas debido a que se trata como una clase de Objective-C y al intentar enviar un mensaje para establecer un valor booleano que sé que es un poco divertido con CoreData originalmente representándolos como NSNumbers.

¿Algunas ideas? Yo mismo creé la clase, no se genera.

EDITAR:

entity.crDate = NSDate() // succeeds entity.completed = false // fails entity.completed.setValue(false, forKey: "completed") //succeeds

Así que para configurar el bool, usar setValue de NSManagedObject funciona pero no los setters directos, aunque para las propiedades que no son bools, puedo configurarlo usando los setters.

ACTUALIZAR:

Mientras verifico esto un poco más, parece que la primera vez que establezco el valor después de obtener de NSEntityDescription, utiliza los métodos de acceso Swift normales. Más adelante, cuando trato de acceder al mismo objeto (que estaba almacenado en una matriz), trata de tratarlo como un objeto de estilo Objective-C y envía un mensaje para el método llamado "setCompleted". Supongo que tiene sentido ya que uso la notación de puntos para acceder a ella y usé la directiva @objc.

Probé esto creando un método "setCompleted", sin embargo, en el método establezco el valor usando "completed = newValue" que realiza una llamada recursiva a "setCompleted" causando que se bloquee ... Extraño, por lo que en este momento todavía puedo No tengo una solución adecuada. Parece que solo pasa con Bools.

La única solución es usar el método "setValueForKey" de NSManagedObject. Tal vez archivar esto como un informe de error?


Descubrí que funciona bien si especifica el nombre de la clase y el módulo en el modelo de datos (en lugar de dejar el NSManagedObject predeterminado).

Una vez que establezca eso, puedo usar Bool , Int16 , Int32 , etc., sin ningún problema.


En XCode 8 Just set:

user.isLoggedIn = true

funciona como un encanto



Puede reducir su propiedad de tipo NSNumber a Bool de la siguiente manera:

var someBoolVariable = numberValue as Bool

Funciona para mí de esta manera:

self.twoFactorAuthEnabledSwitch.enabled = userProfile?.twoFactorEnabled as Bool


Si permite que Xcode 6 Beta 3 cree los archivos Swift para sus entidades, creará NSNumber propiedades CoreData para Boolean tipo Boolean de CoreData .

Sin embargo, puedes usar Bool como un tipo Swift en lugar de NSNumber, aunque funcionó para mí sin usar la sintaxis de puntos . Establecerá el Swift Bool con un NSNumber , que tal vez conduce a un error en la sintaxis de puntos.

Para hacerlo explícito, debe usar el tipo NSNumber para los atributos en la entidad con el tipo Boolean . Luego cree una propiedad computada (en iBook El lenguaje de programación Swift en Guía de idiomas -> Propiedades -> Propiedades calculadas) para devolverle un Bool Swift. Así que nunca realmente almacenaría un Bool .

Al igual que:

@NSManaged var snack: NSNumber var isSnack: Bool { get { return Bool(snack) } set { snack = NSNumber(bool: newValue) } }

Por supuesto, sería bueno ocultar el otro (atributo NSNumber), pero tenga paciencia y Apple implementará atributos privados en el futuro.

Editar:

Si marca la casilla crear tipos de skalar , ¡incluso utilizará el tipo Bool en el archivo Swift creado automáticamente!

Así que creo que es un error.


Siguiendo de CH Buckingham que es del todo correcto. Está intentando almacenar un tipo primitivo en los datos del núcleo donde está esperando un NSNumber.

El uso correcto sería entity.completed = NSNumber.numberWithBool(false)

Esta es también la razón por la que no puede recuperar este valor completado como un bool directamente y, por lo tanto, tendría que escribir:

var: Bool? = entity.completed.boolValue()