NSSearchfield et vitesse d'exécution

chaps31chaps31 Membre
07:29 modifié dans API AppKit #1
Bonjour à  tous,

Juste une question, j'utilisais un NSSearchField via sa méthode delegate héritée :
- (void)controlTextDidChange:(NSNotification *)aNotification


Puis je me suis dis, quand même c'est un control fait pour être utilisé en target-action. Donc j'ai créé un IBAction et j'y ai mis le code qui se trouvait dans la méthode délégué précédente, j'ai viré le delegate dans IB et mis un lien pour l'action.

Ca marche évidement pareil sauf que à  ma grande surprise, c'est moins rapide... L'action entraine un
filterUsingPredicate
sur un tableau source d'une tableview. Ce tableau ne contient actuellement que 15 lignes (en utilisation réelle il y a aura peut-être 5000 lignes) et si via la méthode délégate hérité c'est instantané, via l'IBAction il y a un très court temps de latence (< à  1 sec.)...

La méthode délégué est réellement plus rapide ??? C'est étrange... Car si là  c'est pour une fraction de seconde, lorsqu'il y aura plus de 1000 lignes..

Votre expérience dans la vitesse de
- (void)controlTextDidChange:(NSNotification *)aNotification
par rapport au target-action ?

Merci de vos lumières .

Réponses

  • Philippe49Philippe49 Membre
    07:29 modifié #2
    Ton control est en mode Continuous ?
  • chaps31chaps31 Membre
    janvier 2009 modifié #3
    Non, qu'est-ce que ça change ?   :)beta:

    EDIT : Une autre remarque, je viens de découvrir un truc, c'est qu'avec la méthode délégué effacer un caractère dans le searchfield lance la méthode mais pas avec l'IBAction... Cette dernière ne se lance que lorsque l'on tape un caractère... Vous confirmez ? Si c'est le cas j'abandonne l'IBAction.
  • Philippe49Philippe49 Membre
    07:29 modifié #4
    En mode continuous, chaque changement dans le texte provoque l'envoi de l'action. Si tu tapes  Toto en mode continuous l'action est exécuté 4 fois comme avec la notification textDidChange, autrement la recherche n'est lancée que lorsque l'utilisateur tape Enter.
    Il faudrait voir si le temps de latence que tu remarques n'est pas simplement ce temps de frappe de la touche Enter , et peut-être aussi essayer de profiter dans ton code des appels multiples, en filtrant des tableaux déjà  filtrés . 
     
  • chaps31chaps31 Membre
    07:29 modifié #5
    Il me semble que par défaut le nssearchfield envoie à  chaque frappe clavier l'action, il faut cocher "Send Whole Search String" pour que l'action ne soit plus envoyée qu'à  la pression de la touche return.

    D'ailleurs ma tableview se modifie à  chaque frappe clavier sans que continuous ne soit coché, cela n'arrive plus si je coche "Send Whole Search String". Continuous semble servir à  autre chose.
    Donc l'action et la méthode délégué font rigoureusement la même chose, bizarre ce délai avec l'action par rapport à  la méthode délégué.
    Comme tu le dis je peux améliorer mon code, mais de toute manière la méthode délégué sera toujours plus rapide et reste le problème de l'effacement pris en compte par la méthode délégué et pas par l'action... Je sens que je vais repasser en méthode délégué... Une autre idée pour ce ralentissement avec l'action et pour les effacements non pris en compte ?

    Merci de tes réponses.
  • chaps31chaps31 Membre
    janvier 2009 modifié #7
    :P

    Déjà  parcourue, mais j'y retourne.

    EDIT : pour l'effacement, erreur de code de ma part, plus de problème.  :)beta:
    Pour la vitesse mystère, c'est une curiosité.

    Sinon, puisque je suis sur les searchfield, j'ai beau chercher je n'arrive pas à  activer le menu du searchfield, je le crée pas de problème, mais par contre toutes les item restent grisées...  :-\\
  • Philippe49Philippe49 Membre
    07:29 modifié #8
    Pour la vitesse, je constate la même chose ... avec une table view de 100 000 lignes, un léger décalage d'une demi-seconde, qui ne me semble pas plus important que lorsque il n'y a que 100 lignes. Curieux.


    dans 1231928109:

    EDIT : Une autre remarque, je viens de découvrir un truc, c'est qu'avec la méthode délégué effacer un caractère dans le searchfield lance la méthode mais pas avec l'IBAction... Cette dernière ne se lance que lorsque l'on tape un caractère... Vous confirmez ? Si c'est le cas j'abandonne l'IBAction.

    Non je ne confirme pas, l'IBAction est lancé à  l'effacement d'un caractère, et à  l'effacement total.
  • chaps31chaps31 Membre
    07:29 modifié #9
    Pour l'effacement c'est de ma faute erreur de code, ca marche très bien en effet. Merci pour le test à  100 000 lignes, curieux que le décalage reste le même quelque soit le nombre de ligne.... Après entre 1/2 sec et instantané, l'instantané est toujours plus agréable ;)

    Merci encore pour tes réponses et ton test sur la vitesse. Sinon... Je ne voudrais pas abuser...  ::) Mais tu sais comment rendre les menus des nssearchfield actif, non grisés ? Merci  :why?:
  • Philippe49Philippe49 Membre
    07:29 modifié #10
    dans 1232015262:

    Mais tu sais comment rendre les menus des nssearchfield actif, non grisés ? Merci  :why?:

    Il y a une manip spéciale pour faire apparaà®tre ce menu ?
  • chaps31chaps31 Membre
    07:29 modifié #11
    On instancie un menu dans IB puis on lie le menu au "searchMenuTemplate" du nssearchfield. Ca marche très bien, on compile et un joli menu cliquable est présent dans le nssearchfield via un petit triangle, mais toutes les items restent désespérement grisées, quoique je fasse... C'est la misère ... :-\\
  • Philippe49Philippe49 Membre
    07:29 modifié #12
    Ok merci, dans mon essai j'avais connecté à  "menu" et non à  "searchMenuTemplate". C'était idiot.

    La réponse à  ton problème est en encadré page 14 du Search Fields Guide : Mettre 1001 dans le tag de l'item du menu, pour les autres options d'un tel menu, mettre 1000, 1002, 1003.
  • chaps31chaps31 Membre
    07:29 modifié #13
    Les grands esprits se rencontrent j'étais en train de chercher dans ces tag dans la doc, mais je n'y arrive malheureusement pas...

    J'ai plusieurs NSSearchfield, plusieurs auront des menus, dans le premier que j'essaie de créer il y a 3 item "supérieur à  " "inférieur à  " et "egal à  ", en fonction de l'item sélectionnée dans xcode la comparaison changera et entrainera un filtre dans un tableau en datasource d'une tableview.

    En fait je ne suis pas certains de bien comprendre..  :)beta:  pour moi les items des menus sont les choix possible, donc qu'entends-tu par "l'item du menu", j'en ai 3... J'ai essayé de leur mettre les tag 1001 - 1002 - 1003, 1000-1002-1003 même résultat dans les 2 cas et que je ne comprend pas, un seul choix apparait le 1003 et toujours en grisé...  :crackboom:-
  • Philippe49Philippe49 Membre
    janvier 2009 modifié #14
    Pour l'instant, je n'ai mis qu'un item avec le tag 1001. J'ai réglé Max Recents à  5 et j'ai bien les 5 dernières recherches correctement mises à  jour et actives. Elles sont stockées automatiquement dans la plist des préférences.

    [EDIT] si je mets deux item de tag 1001, j'ai le droit à  un doublement , soit 10 items.
  • Philippe49Philippe49 Membre
    07:29 modifié #15
    J'appelle le deuxième item "Clear" avec un tag =1002 et cela efface les recherches récentes.

    J'insère en haut un item avec pour titre "Recherches Récentes", et tag=1000

  • chaps31chaps31 Membre
    07:29 modifié #16
    Je crois que tu réponds bien à  ma question, merci, mais malheureusement ce ne sont pas les recherches récentes qui m'intéressent mais un menu que je puisse remplir pour en fait filtrer la recherche.
    Dans mon cas il s'agit d'un trie de tableau en fonction de la valeur chiffrée rentrée dans le champs de recherche, mais le trie doit pouvoir s'exécuter pour >, < ou =. Je pensais utiliser ce menu pour permettre ce choix, malheureusement j'ai l'impression que ce n'est pas possible...

    Tant pis... je vais passer par une autre voie moins ergonomique, taper > ou < avant le nombre dans la case de recherche...

    Mais pour un autre nssearchfield je vais utiliser les items de dernières recherches, merci
  • chaps31chaps31 Membre
    07:29 modifié #17
    C'est la misère pour un autre nssearchfield j'ai lié son menuTemplate à  un NSMenu, j'ai mis 5 en recents.

    Dans le menu j'ai tapé pour l'item 1 "Eléments récents" avec tag 1000, Item2 non touchée sauf pour le tag (mis à  1001) et item3 "Effacer ce menu" avec tag 1002. Je compile, le petit triangle est présent et.....

    rien... Aucun menu ne s'affiche... :crackboom:-  Si tu vois une erreur évidente à  ma description je suis preneur, pas au top ce système  :P
  • Philippe49Philippe49 Membre
    janvier 2009 modifié #18
    dans 1232094931:

    Dans mon cas il s'agit d'un trie de tableau en fonction de la valeur chiffrée rentrée dans le champs de recherche, mais le trie doit pouvoir s'exécuter pour >, < ou =. Je pensais utiliser ce menu pour permettre ce choix, malheureusement j'ai l'impression que ce n'est pas possible...

    Rien n'empêche à  priori de rajouter un autre item avec une action (connection dans IB) qui change une variable d'instance dans ton contrôleur.

    [EDIT] essai ==> aucun problème
  • Philippe49Philippe49 Membre
    janvier 2009 modifié #19
    dans 1232095715:

    C'est la misère pour un autre nssearchfield j'ai lié son menuTemplate à  un NSMenu, j'ai mis 5 en recents.

    Dans le menu j'ai tapé pour l'item 1 "Eléments récents" avec tag 1000, Item2 non touchée sauf pour le tag (mis à  1001) et item3 "Effacer ce menu" avec tag 1002. Je compile, le petit triangle est présent et.....

    rien... Aucun menu ne s'affiche... :crackboom:-  Si tu vois une erreur évidente à  ma description je suis preneur, pas au top ce système  :P


    Peut-être le choix d'un AutoSaveName (différent du premier) ?

    [EDIT] essai : nouveau NSSearchField, copier-coller du premier menu, mise en place du delegate du search field, et code :

    -(void) controlTextDidChange:(NSNotification*) notif {
    NSLog(@control text did change);
    NSPredicate * predicate=nil;
    NSString * searchString=[[notif object] stringValue];
    if(nil!=searchString && [searchString length]>0){
    predicate=[NSPredicate predicateWithFormat:@%K BEGINSWITH %@",@nom,searchString];
    self.filteredClients=[clients filteredArrayUsingPredicate:predicate];
    }
    }
  • Philippe49Philippe49 Membre
    07:29 modifié #20
    dans 1232094931:

    Dans mon cas il s'agit d'un trie de tableau en fonction de la valeur chiffrée rentrée dans le champs de recherche, mais le trie doit pouvoir s'exécuter pour >, < ou =.

    Personnellement, je mettrais un segmented control à  côté du champ de recherche.
  • chaps31chaps31 Membre
    07:29 modifié #21
    Bon, tu as raison mon idée est pas terrible, ieux vaut garder ce menu uniquement pour les recherches récentes. Faut que je reréfléchisse à  l'ergonomie.
Connectez-vous ou Inscrivez-vous pour répondre.