2010-09-26 8 views
0

Après la migration, l'une de mes valeurs numériques qui devraient être non-zéro apparaît maintenant comme zéro. Si je ne migre pas, la valeur conserve sa valeur non nulle.Core Data Migration perd de sa valeur NSNumber

J'ai d'abord essayé de définir une valeur numérique dans un objet géré comme ceci:

[temp setNumUses:temp.numUses+1]; 

... mais que cela a causé an'EXC_BAD_ACCESS » alors j'ai changé à:

int hold = ((int)[[temp valueForKey:@"numUses"] intValue]); 
hold++; 
[temp setNumUses:[[NSNumber alloc] initWithInt:hold]]; 

. .. mais après la migration, ce code a réclamé que hold a été initialisé comme int avec une valeur de 0 quand avant d'exécuter le nouveau code sa valeur était clairement 1 ou plus (se référant à l'objet de test qui a été utilisé seulement 1 fois).

Quand je ne migrez pas la base de données de données de base du NSNumber conserve sa valeur bien dans de nombreux contexte et enregistre les résiliations d'application.

Que pourrais-je manquer? J'ai un code étendu qui modifie les valeurs de NSManagedObjects modifiées dans une base de données stockée ailleurs, mais aucune d'entre elles ne gère les 'nombres'.

Pensées?

Répondre

0

L'explication la plus simple est que la migration de base de données en quelque sorte persuade que numUses est un nouvel attribut avec la valeur par défaut de zéro. La raison en est le modèle de migration et non le code d'affectation que vous avez fourni.

Cependant, le code dans le parent ne suggère que vous ne comprenez pas tout à fait NSNumber et manquer à l'aide NSNumber ailleurs pourrait causer votre problème.

NSNumber est seulement une enveloppe d'objet autour des valeurs numériques. Vous ne pouvez pas effectuer d'opérations avec. C'est pourquoi cette ligne:

[temp setNumUses:temp.numUses+1]; 

... provoque le EXC_BAD_ACCESS. Comme vous l'avez découvert, vous devez convertir un NSNumber en un int ou un NSDecimalNumber pour effectuer des opérations mathématiques.

Cette ligne:

[temp setNumUses:[[NSNumber alloc] initWithInt:hold]]; 

... sera fuite de mémoire. Vous initialisez un objet NSNumber mais ne le libérez jamais. Dans ce cas (et dans la grande majorité des cas), vous devez utiliser les méthodes de classe pour créer NSNumbers car elles renvoient un objet autoreleased qui ne fuira pas. Alors:

[temp setNumUses:[NSNumber numberWithInt:hold]; 

En pratique générale, il est mauvais pour initialiser un objet dans un paramètre de méthode. Vous demandez des fuites de mémoire désagréables qui seront très difficiles à localiser. Le rapport de la fuite peut ne pas apparaître dans le code où la méthode est appelée mais dans la méthode elle-même.

+0

Salut, je voudrais souligner que je suis relativement nouveau à la programmation avec Objective-C. J'ai essayé la méthode de la classe NSNumber avant l'allocation mais je voulais couvrir toutes mes bases juste pour être sûr. Toujours eu le problème de la valeur NSNumber étant 0 de toute façon. Y a-t-il des conseils que vous pouvez me donner sur les modèles de migration de données de base? Pour migrer la base de données dans mon code j'ai simplement suivi un guide pour ajouter la migration automatique, y a-t-il une meilleure façon/solution facile de résoudre ce problème en utilisant cette méthode encore? –

+0

En outre, pourquoi: [temp setNumUses: temp.numUses + 1]; finir travailler? J'ai écrit ce code il y a un certain temps, qui a depuis été remplacé mais qui fonctionnait avant la migration.Y a-t-il des méthodes d'opérateur écrites dans NSNumber? Ou est-ce que ceux-ci n'existent pas? Merci! –

+0

NSNumber n'a pas de méthodes d'opérateur. Vous ne pouvez pas simplement ajouter un scalaire à un objet NSNumber. Si vous essayez, vous incrémenter l'adresse de l'objet. Je ne sais pas pourquoi votre migration échoue. – TechZen

Questions connexes