2009-07-27 6 views
6

Dans mon modèle de données de base, j'ai une entité avec un attribut NSNumber facultatif.Stockage du numéro NSNumber facultatif dans les données de base

Comment puis-je tester si la valeur de cet attribut est valide ou non?

Lorsque je ne vérifie rien ... ne fonctionne pas.

[self numberAttribute] == nil // always returns NO 

Lorsque je teste un int de valeur nulle, cela ne fonctionne pas.

[[self numberAttribute] intValue] == 0 // always returns no 

En fait, [[self numberAttribute] intValue]] quelque chose qui ressemble retours étrangement à un pointeur vers une adresse mémoire.

Quelqu'un at-il une idée de ce que je fais de mal?

EDIT: OK, le bogue était dans une partie totalement indépendante du code. NSNumber et Core Data fonctionnent exactement comme on pourrait s'y attendre. Cela dit, je vais aller avec l'approche suggérée de rendre l'attribut non-optionnel et en spécifiant 0 comme valeur par défaut.

Juste en mettant cette note ici pendant un petit moment pour quelqu'un qui regardait cette question, alors je la supprime.

+1

Je n'ai pas encore assez de rep pour éditer, mais votre deuxième exemple de code a des parenthèses déséquilibrées (2 parenthèses d'ouverture et 3 fermant). – Mark

+0

Merci beaucoup. Fixé. – mmc

+0

numberAttribute est spécifié comme flottant dans le modèle de données? Comment la propriété pour numberAttribute est-elle déclarée? A quoi ressemblent les implémentations d'accesseurs (si vous n'utilisez pas d'accesseurs @dynamic.) Sans cette information, votre question est impossible à répondre avec précision. –

Répondre

0

Si vous obtenez une grande valeur en arrière qui ressemble à un pointeur, peut-être que c'est NaN (pas un nombre)?

Si oui, vous pouvez vérifier avec:

isnan([[self numberAttribute] doubleValue]) 

Ou, peut-être il est une autre constante le long des lignes de NSNotFound (mais probablement plus spécifique de base de données).

+0

Essayé plusieurs saveurs différentes de cette technique, n'a pas fonctionné. La valeur que j'obtiens n'est pas une constante, et il signale dans le débogueur (colonne Résumé) comme "Invalide". C'est assez bizarre, je suppose que si je n'ai pas défini l'attribut du tout, et s'il a été marqué comme "optionnel" avec une valeur par défaut de "0" dans le .xcdatamodel, cela ne serait pas si difficile à accomplir. – mmc

+0

Si vous l'avez marqué comme facultatif, la valeur par défaut ne serait pas définie ... Je pense que vous récupérez fondamentalement un type d'objet invalide qui représente un état indéterminé. Je ne peux pas trouver dans Core Data comment vous êtes censé reconnaître un objet invalide ... –

+0

J'ai vérifié avec quelqu'un d'autre qui a un projet Core Data fonctionnant avec des attributs optionnels - il pensait qu'une valeur non définie devrait en fait être nulle, juste comme vous étiez en train de vérifier. Donc j'irais avec la théorie que vous récupérez un objet NSNumber comme porneL postulait. –

5

Selon le documentation,

Vous pouvez spécifier qu'un attribut est facultatif qui est, il est pas nécessaire d'avoir une valeur. En général, cependant, vous êtes découragé de le faire, en particulier pour les valeurs numériques (généralement, vous pouvez obtenir de meilleurs résultats en utilisant un attribut obligatoire avec une valeur par défaut - dans le modèle - de 0). La raison en est que SQL a un comportement de comparaison spécial pour NULL qui est différent de celui de Objective-C. NULL dans une base de données n'est pas la même chose que 0 et la recherche de 0 ne correspondra pas aux colonnes NULL.

false == (NULL == 0) 
false == (NULL != 0) 

De plus, NULL dans une base de données ne équivaut pas à une chaîne vide ou blob de données vide, soit:

false == (NULL == @"") 
false == (NULL != @"") 

Alors, essayez un test avec NULL, qui est pas nul. Mieux encore, définissez une valeur par défaut et modifiez l'attribut pour qu'il ne soit pas facultatif. C'est ce que j'ai fini par faire avec mes modèles, et en pratique ça marche plutôt bien.

Modifier: Voir mon commentaire ci-dessus. J'ai essayé de créer un nouvel objet géré avec un attribut optionnel non défini, et il était nul.

BOOL isNil = ([newManagedObject numberAttribute] == nil); //equals YES 

Une autre édition: je suis revenu à plus tard et vérifié sur un objet chargé à partir du cache dans le débogueur (GDB est votre ami!). Il essayait d'accéder à l'emplacement de mémoire 0x0, qui est NULL.

+0

Oui, mais la vraie question est de savoir si vous avez un attribut déclaré facultatif - comment vérifiez-vous s'il est défini ou non? –

+0

True. J'ai fait d'autres vérifications et ajouté des détails à ma réponse. – Don

+0

Je suis d'accord maintenant que c'est le chèque approprié, le mystère est qu'il ne va pas nil, mais une valeur étrange ... –

0

S'il ressemble à un pointeur, il peut s'agir d'un pointeur sur l'instance NSNumber. Assurez-vous de ne pas avoir de discordance entre le modèle de données de base et la classe (par exemple NSIntegerNSNumber* est attendu).

Si vous avez un scalaire dans votre classe, alors vous devez le noter vous-même dans setNilValueForKey:.

+1

Cela semble très probable pour moi un bien (pas que quelqu'un avec ce chapeau génial a besoin de sauvegarde en aucune façon). –

Questions connexes