49 votes

Quelle est la cause de cette erreur ? "CALayer position contains NaN : [240 nan]".

J'ai constaté que cela se produisait lorsque je faisais pivoter un écran qui avait une UITableView sur celui-ci. J'ai découvert que cela se produit entre le willRotate y didRotate dans les appels de méthode de l UIViewController Mes collègues l'ont également vu à d'autres endroits, généralement autour de la rotation. Cela n'a commencé à se produire que très récemment, et nous ne savons pas comment le traiter (les recherches sur Google ne donnent pas le message d'erreur dans sa forme exacte). Est-ce que quelqu'un d'autre a rencontré ce problème et sait ce qu'il faut faire ?

41voto

Olie Points 10528

(J'ai décidé de retirer cette question des commentaires et de la placer comme réponse, car je pense que c'est une très bonne réponse :)

Ha ! J'avais aussi un calcul NaN (div0). Aide au débogage : le message en question est produit par NSLog(), donc mettez un point d'arrêt sur NSLog() et regardez ce que fait le système d'exploitation à ce moment-là. Pour moi, c'était myUISlider.value = NaN.

Pour définir le point d'arrêt :

XCode 3.x

  • CMD-SHIFT-Y (fenêtre de débogage)
  • Bouton Points d'arrêt.
  • "Double-clic pour le symbole
  • Tapez "NSLog" (sans guillemets).

XCode 4.x

  • CMD-6 (navigateur de points d'arrêt)
  • "+" pour ajouter un point d'arrêt (en bas à gauche)
  • Sélectionnez ADD SYMBOLIC BREAKPOINT (ajouter un point de rupture symbolique).
  • Symbole : NSLog
  • Confirmer : Terminé.

XCode 5.x - 7.1 (au moins) (Identique à la version 4.x, sauf que le navigateur de points d'arrêt est désormais CMD-7).

Exécutez l'application, regardez-la se casser sur NSLog, vérifiez les traces de pile.

1 votes

C'est la réponse qui importe réellement dans le cadre de cette exception. Il est important de noter que cette exception peut être soulevée par des composants qui utilisent le CALayer et que nous, utilisateurs de l'API, ne connaissons pas leur existence (grâce à l'encapsulation).

0 votes

Morkrom, vous pensez à la version iOS. Je parle de la version XCode. Je n'ai pas encore eu l'occasion de vérifier XCode 5.x, mais je parie que ce n'est pas trop difficile à comprendre.

1 votes

Très bien, +1 pour l'approche de débogage.

28voto

Kevlar Points 3988

J'ai trouvé le problème.

Lorsque vous réinitialisez le cadre d'un tableview il appelle la méthode de délégation tableView:heightForRowAtIndexPath: pour chaque ligne du tableau afin de pouvoir recalculer la taille de son contenu si nécessaire. À ce stade, nous effectuons une manipulation spéciale pour renvoyer la hauteur, et en raison de mauvaises hypothèses dans notre code, nous avons renvoyé par erreur NaN en raison d'une erreur de division par zéro (la variable par laquelle nous divisons a été supposée ne jamais être nulle). Le fait de s'assurer que l'on ne divise pas par zéro ici a permis de résoudre le problème.

0 votes

J'obtiens la même erreur (la position et les limites contiennent NaN, les messages viennent généralement par paires) juste avant que ma vue ne s'affiche. Pas de rotation, pas de tableaux, pas de calculs fantaisistes. Une simple vue gris foncé avec un libellé "Processing..." et un indicateur de progression. Quelqu'un d'autre a des idées sur ce sujet ?

1 votes

Mettez des points d'arrêt dans vos méthodes viewdidload/viewwillappear et assurez-vous que vous ne divisez pas par zéro accidentellement.

0 votes

Cela peut être pertinent ou non, mais j'ai vu ce crash beaucoup plus régulièrement dans Mavericks OSX 10.9, mais il n'a pas été revu après la mise à jour OSX 10.9.2.

16voto

azernitsky Points 71

J'ai passé une journée à essayer de trouver le code qui cause le même problème et je l'ai résolu en quelques minutes après avoir activé "break on exception" dans Xcode. Vérifier ce tutoriel pour savoir comment l'activer.

1 votes

Pouvez-vous inclure un bref résumé du contenu de la page ? Ceci afin que les futurs lecteurs de cet article puissent obtenir rapidement et facilement les informations qu'ils recherchent.

3 votes

@gobernador Je le ferai car cela m'a aidé ! Pour trouver la ligne exacte où votre application est morte, allez dans l'onglet breakpoint sur la gauche de xcode, cliquez sur +, ajoutez un nouveau Exception Breakpoint et laisser les paramètres par défaut. Cliquez sur Terminé et réexécutez votre application.

13voto

Grady Player Points 7823

J'ai eu ce problème lorsque j'étais supposé que.. :

tableView:heightForHeaderInSection: a renvoyé un NSInteger mais il renvoie CGFloat ...

changeant :

-(NSInteger)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

à

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

a résolu mon problème.

Edita:

A un moment donné, j'ai compris comment les ordinateurs fonctionnent en dessous du niveau C, alors j'ai pensé que je pourrais le partager... (J'utiliserai les noms des registres de x86_64 car ils me sont plus familiers, ARM serait légèrement différent mais analogue).

int f(){
          float someFloat=5.0f;
          return someFloat;
       }

a pour effet de convertir la valeur de someFloat à un type d'entier, puis de le copier dans un registre particulier : %rax puis en appelant l'instruction de retour.

float f(){
          float someFloat=5.0f;
          return someFloat;
       }

a pour effet de copier la valeur de someFloat de son emplacement actuel à un registre particulier : %xmm0 puis en appelant l'instruction de retour.

Ainsi, si vous avez le mauvais prototype, le code appelant s'attendra à ce que la valeur soit au mauvais endroit, et vous finirez par renvoyer une valeur erronée.

3voto

Z.L.Chen Points 46

Cette erreur m'a également coûté beaucoup de temps.
À la fin, j'ai trouvé que mon collègue avait écrit quelque chose comme ceci :

UIEdgeInsets a;
a.left = (...some calculation);
button.imageEdgeInsets = a;

J'ai réécrit le code comme suit et j'ai résolu le problème :

UIEdgeInsets a;
a.left = (...some calculation);
a.top = 0;
a.bottom = 0;
a.right = 0;
button.imageEdgeInsets = a;

certaines valeurs de UIEdgeInsets ne sont pas initialisées correctement, et il arrive qu'elles se transforment en valeur NaN, ce qui fait planter l'application.
Plus généralement, vous devez vérifier que toutes les valeurs des structures de style C sont initialisées correctement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X