Exemple de comportement différent de code iOS selon qu’il s’exécute sur émulateur ou device

- Exemple de comportement différent de code iOS selon qu’il s’exécute sur l’émulateur ou un device (la machine, i.e. iPhone/iPad) :

Soit le code iOS suivant (qui permet de consulter un tableau comme s’il était bouclé sur lui même) :
NSUInteger p0_prevIndex;
 p0_prevIndex = p0Index – diffAtP0;
if(p0Index < diffAtP0)
  p0_prevIndex += iPoints.count;

(le test équivaut à (p0_prevIndex < 0), qui évidemment ne pourrait arriver que s’il était de type NSInteger)

Le code fonctionne parfaitement sous émulateur mais conduit à un crash à la ligne suivante (non représentée), à la lecture du tableau (lecture à l’index p0_prevIndex alors que celui-ci vaut iPoints.count)

La lecture des valeurs à la 3° ligne donne

 (lldb) pri p0Index
 (NSUInteger) $3 = 0
 (lldb) pri diffAtP0
 (CGFloat) $2 = 2
 (lldb) pri p0_prevIndex
 (NSUInteger) $5 = 0

->p0_prevIndex devrait valoir (NSUInteger)(-2) (soit 4294967294, peu importe), et donc (iPoints.count-2) juste après.

Affichage d’autres valeurs :

 (lldb) pri p0Index – diffAtP0
 (float) $4 = -2

-> OK

 (lldb) pri p0_prevIndex = p0Index – diffAtP0
 (NSUInteger) $6 = 0

-> pourquoi ? On devrait obtenir la valeur correspondant à -2…

 (lldb) pri p0_prevIndex = -2
 (NSUInteger) $7 = 4294967294

-> OK, l’affectation directe fonctionne.

Le pb vient d’un typecast, car diffAtP0 est de type CGFloat (en fait le type des iPoints).
Le déclarer en NSUInteger apporte la solution.

La vraie remarque est que le crash ne survient sur aucun des émulateurs car le typecast effectué est alors correct.

Social tagging: >

Laisser un commentaire