(remarqué la première fois sur: Xcode 8.2.1, iOS 10, Swift 3) (toujours présent en tant que: Xcode 9 beta 3, iOS11, Swift 4)
Nous savons tous que le concept Core Data
de optionals
précède et n’est pas strictement lié au concept Swift
de optionals
.
Et nous avons accepté le fait que même si un attribut Core Data
est marqué comme étant Non-optional
, la sous-classe NSManagedObject
générée automatiquement a un type optional
:
(Certaines personnes suppriment manuellement le ?
sans aucun effet indésirable, d'autres non, mais ce n'est pas la question)
(À partir de cet exemple, l'exemple et les captures d'écran concernent les propriétés Bool
, mais il en va de même pour Int16/32/64
, Double
, Float
)
Maintenant, j'ai remarqué l'inverse: lorsqu'un attribut Core Data
de type Bool
est marqué comme étant Optional
(et que Use Scalar Type
est choisi, ce que Xcode fait par défaut), la classe générée automatiquement a une variable de type non-optional
.
Est-ce que ça a du sens? Est-ce un bug? Le comportement est-il documenté quelque part?
Et surtout - comment est-ce que je représente réellement une Bool
optionnelle?
Je peux penser à quelques solutions de contournement, mais elles ne semblent pas idéales (par exemple, ne pas utiliser de scalaires, mais revenir à la représentation NSNumber
de la Bool
. Ou (pire encore) d'avoir un Bool
séparé appelé isVerified_isSet
)
Remarque: J'ai fait quelques tests supplémentaires et si le Default Value
est défini sur None
ou sur NO
, la variable est alors enregistrée en tant que false
(même si je ne l'assigne jamais dans mon code). Si le Default Value
est défini sur YES
, la variable est enregistrée en tant que true
. Néanmoins, cela signifie que (apparemment) il n’ya aucun moyen de représenter logiquement cette variable comme n’ayant pas encore été définie.
Je vois la même chose, et je considère que c'est un bug. Ce n'est documenté nulle part où je peux trouver. Apparemment, Core Data applique ici les hypothèses de style Objective-C, où un booléen est défini par défaut sur NO
et un nombre entier par défaut sur 0. L'interface Core Data/Swift présente certaines aspérités, que je n'avais pas envisagée auparavant.
C'est une bonne trouvaille, mais je pense que vous êtes coincé avec cette question jusqu'à ce que Apple vous en parle. Vous connaissez déjà les meilleures solutions de contournement, ce qui, à mon avis, ne sont pas géniales. Je recommande de déposer un bogue.
Cela est dû au fait que les types scalaires Objective-C n’ont pas de notion de valeur nulle. Source: traitement-base-données-optionnel-scalaire-attributs
Si vous vous retrouvez ici avec ceci:
@NSManaged var boolAttribute: Bool
et cela ne se voit pas dans Objective-C, et vous avez déjà désactivé "Facultatif" et activé "Utiliser le type scalaire" sur ces attributs, alors faites-vous plaisir.
Vérifiez que vous avez importé votre en-tête de pontage Swift dans ce fichier Objective-C.
Je ne l’ai pas fait et, eh bien, c’était la plupart du temps que je changeais mes Bools en NSNumbers avant de me claquer la tête et de me rendre compte à quel point j'étais idiot.