comportement erratique d'un NSNumberFormatter sur un NSSearchField
iApasDeMal
Membre
Bonjour à tous,
j'ai un NSSearchField pour déclencher une action à chaque saisie de texte :
IBOutlet NSSearchField * numericSearchField;
je lui applique un formateur comme ça :
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[numericSearchField setFormatter:formatter];
[formatter release];
formatter = nil;
Mais le formatage ne se fait pas du tout correctement, il efface l'ensemble de la saisie de texte quand j'insère un caractère non numérique et d'autres comportements étranges.
À quoi c'est dû?
merci d'avance pour vos idées
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Le NSSearchField dispose de facilité pour faire des recherche texte (en fait c'est plutôt le NSSearchFieldCell qui en dispose).
Faire des recherches avec un NSNumber doit vraisemblablement nécessiter pas mal de customisation.
Merci de répondre si vite.
Donc à ton avis je n'utilise pas le bon contrôle pour formater - mettre en forme et corriger - à la volée les saisies de textes de l'utilisateur?
J'ai fait un essai avec un NSTextField qui reçoit des actions à chaque frappe du clavier grâce à :
J'ai des problèmes similaires.
Devrais-je en conclure que les NSNumberFormatter ne permettent pas de formater du texte à la volée?
Bonjour,
Je passais par là et j'en profite pour poser une question. Je travaille avec ARC, c'est donc une pure question de curiosité. Les lignes de iApasDeMal :
font quoi une fois compilées? Pour l'ancien programmeur Pascal que je suis, cela équivaut à faire
mais en Objective-C je suppose que c'est différent. Est-ce que le setFormatter utilise une copie du NSFormatter, laissant l'original suspendu dans le vide? Est-ce que cet original est détruit lorsque le programme quitte la méthode? Est-ce que le release ne remet pas l'adresse à nil?
Merci de m'éclairer si vous avez du temps, ce n'est pas prioritaire.
Si tu n'es pas au point sur ces concepts, c'est très urgent pour toi de te documenter dessus, car c'est quand même une des bases structurantes de la gestion mémoire. Et ARC ne change pas grand chose au problème d'ailleurs : certes avec ARC tu n'as pas à appeler retain ou release c'est lui qui se charge de libérer la mémoire au besoin. Mais ça n'enlève pas que les concepts de "strong references" ou "weak references" sont un concept important à connaà®tre. Car même avec ARC, si tu mets une weak reference au lieu d'une strong reference qqpart, y'a des choses qui vont mal se passer...
Si, justement, c'est pour ça que je ne comprends pas le code de iApasDeMal...
Autrement dit, c'est bien à toi de releaser le formatter car c'est toi qui l'a alloc/init, donc c'est de ta responsabilité d'équilibrer tout alloc ou retain ou copy par un release ou autorelease. Après, c'est `setFormatter` qui se préoccupe de faire un `retain` de son côté du formatter qu'on lui passe, s'il a besoin d'en garder une référence (ce qui est le cas s'il ne veut pas risquer que le formatter soit détruit entre temps).
De toute façon si `setFormatter:` ne faisait pas le `retain` en interne, alors tu aurais un crash assuré (et non l'équivalent d'avoir fait un `setFormatter:nil` comme tu semblais le penser dans ton message plus haut). Ou alors faudrait pas faire le `release` de ton côté pour pas que ça crash (et ça serait toujours pas équivalent à `setFormatter:nil` de toute façon) mais ça violerait la règle de base de Cocoa sur la "ownership responsability".
Si `setFormatter:` retenait une `weak reference` mais qu'on tournais sous iOS4, ou si c'était une `unsafe_unretained reference` sous iOS4 ou suppérieur, alors tu aurais un crash. Si tu avais une `weak reference`sous iOS5 ou supérieur, et donc que le mécanisme de "Zeroing Weak Reference" (ZWR) était actif (mécanisme qui fait que les références vers les objets qui sont depuis détruits se remettent à nil automatiquement), tu aurais un formatter remis à nil car tu l'aurais détruit depuis. Tout cela n'aurais pas trop de sens à l'usage et ne respecterais pas les conventions de Cocoa quant aux setters sur des NSObject et aux principes d'objets owners (composition). Mais heureusement et évidemment, `setFormatter:` maintiens une `strong reference` sur le formatter, ce qui parait logique vu les conventions Cocoa et le fonctionnement naturel attendu.
Si tout cela n'est pas clair ni naturel pour toi, c'est qu'il te faut réviser ce qu'il y a sous la notion de `strong reference` En particulier le fait que chacun est responsable des objets qu'il crée (ownership responsability) " concept qui a moins besoin d'être connu avec ARC car ARC gère ça pour nous " et surtout les concepts de strong/weak references (qui est vrai avec ou sans ARC, lui) qui sont primordiales pour éviter les retain cycles.
Après cette importante mise au point,
Existe-t-il un moyen d'utiliser un NSNumberFormatter pour formater un champ de saisi à la volée, c'est à dire après chaque entrée au clavier?
Sinon cela voudrait dire qu'il faudrait que je revienne à ce bout de code
Bout de code qui ne permet pas toutes les subtilités que possède un NSNumberFormatter
Non, je teste ça tout de suite, merci du tuyau.
Je viens de tester, j'ai des erreurs bizarres que ce soit sur un NSTextField ou un NSSearchField : quand j'entre plus de 4 chiffres, l'affichage revient à zéro, plus de chiffre, et quand j'entre autre chose qu'un chiffre, tout l'affichage s'efface.
Peut-être que ce sont les symptômes d'une erreur ou d'une mauvaise manipulation qui te dit quelque chose.
Je vais continuer de regarder.
Parce que bon j'ai pas utilisé de NS*Formatter depuis une paye donc je ne saurai pas t'aider en direct, mais l'info est forcément dans la doc, et de toute façon ça ne fait jamais de mal de lire les Programming Guides qui regorgent d'infos intéressantes voire primordiales
Je les ai regardé en diagonal et donc sans doute trop vite, je vais m'y replonger