Problème de Fluidité avec NSTableView

dakujadakuja Membre
02:48 modifié dans API AppKit #1
Bonjour à  tous,

je me suis fait une petite application contenant une NSTableView et j'utilise une classe DataSource pour la remplir. Hélas, lorsque je dépasse un certain nombre d'entrée (à  partir d'une trentaine), le défilement et le rafraà®chissement est relativement lent, et ça saccade par moment.

J'utilise un objet de type NSArray en tant que DataSource. Pour remplir chaque cellule, j'utilise simplement la commande

[[maNSArray objectAtIndex:rowIndex] valueForKey:identifier]<br />



J'ai pas mal cherché sur le net et je n'ai pas réussi à  trouver de tutorial expliquant comment optimiser plus finement une datasource pour une NSTableView. Est ce qu'il y a des choses à  faire absolument ? D'autres à  éviter ?



Si certains en ont le courage, je joint mon projet. La NSTableView est celle contenant les transactions (transactionTableView), l'objet contenant la liste des transactions affichées est l'objet transactions dans la classe Compte.

Il est possible que la structure du projet puisse vous faire bizarre, c'est mon second projet avec Xcode et Objective C alors ça ne doit pas être top.

Réponses

  • laudemalaudema Membre
    02:48 modifié #2
    dans 1243703897:


    J'ai pas mal cherché sur le net et je n'ai pas réussi à  trouver de tutorial expliquant comment optimiser plus finement une datasource pour une NSTableView. Est ce qu'il y a des choses à  faire absolument ? D'autres à  éviter ?


    Il me semble que le plus facile pour optimiser est d'utiliser les bindings et un NSArrayController. Je dis ça parce que je n'ai encore jamais utilisé ta méthode dans mon apprentissage.
    Sinon, logiquement, ton problème vient de ce que tu fais dans objectAtIndex:rowIndex->valueForKey, le temps que ça met est à  multiplier par le nombre de lignes ..
    D'ailleurs dans sa doc, quelque part, Apple dit que cette méthode doit être optimisée (je sais plus où)
  • tabliertablier Membre
    02:48 modifié #3
    Aaron Hillegass conseille de programmer la méthode 'delegate':
    - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
    

    et d'envoyer un "reloadData" au tableview pour faire la mise à  jour.
    J'ai utilisé cette méthode dans mon appli et cela paraà®t donner de bons résultats.
      :P Mais... c'est mon appli, pas la tienne!!
  • Philippe49Philippe49 Membre
    02:48 modifié #4
    dans 1243703897:

    je me suis fait une petite application contenant une NSTableView et j'utilise une classe DataSource pour la remplir. Hélas, lorsque je dépasse un certain nombre d'entrée (à  partir d'une trentaine), le défilement et le rafraà®chissement est relativement lent, et ça saccade par moment.


    Cela ne provient pas de l'utilisation traditionnelle du data source mais de ton code
    Avec un exemple de datasource de 10000 lignes (une string + une image de 4 Ko par ligne) et une action qui transforme une cinquantaine de lignes :

    Temps de chargement du model : 0,06 seconds<br />Premier reloadData :&nbsp; 0,01 seconds<br />Temps de la modification et du reloadData : 0,001
    

  • dakujadakuja Membre
    02:48 modifié #5
    Merci pour vos réponses, je vais continuer de rechercher ce qui ne convient pas pour accélérer tout ça :)
  • Philippe49Philippe49 Membre
    02:48 modifié #6
    Le code de l'essai ci-dessus

    <br />#import &quot;AppController.h&quot;<br />extern int<br />gettimeofday(struct timeval *restrict tp, void *restrict tzp);<br />#define ROWCOUNT 10000<br /><br /><br />@implementation AppController<br />-(void) awakeFromNib {<br />	struct timeval tv;<br />	gettimeofday(&amp;tv,0);<br />	unsigned long long t0 = tv.tv_sec*1000*1000+tv.tv_usec;<br />	<br />	model=[[NSMutableArray alloc] init];//WithCapacity:ROWCOUNT];<br />	NSImage * image0=[NSImage imageNamed:@&quot;one&quot;];<br />	NSImage * image1=[NSImage imageNamed:@&quot;two&quot;];<br />	NSImage * image2=[NSImage imageNamed:@&quot;three&quot;];<br />	for(NSUInteger index=0;index&lt;ROWCOUNT;index++) {<br />		NSDictionary * dict=<br />			[NSDictionary dictionaryWithObjectsAndKeys:<br />				[NSString stringWithFormat:@&quot;objet %d&quot;,index],@&quot;firstColumn&quot;,<br />			 ((index%3==0)? image0 : (index%3==1)? image1 : image2 ) ,@&quot;secondColumn&quot;,<br />			 nil];<br />		[model addObject:dict];<br />	}<br /><br />	<br />	gettimeofday(&amp;tv,0);<br />	unsigned long long t1 = tv.tv_sec*1000*1000+tv.tv_usec;			<br />	NSLog(@&quot;chargement : %.3f&quot;,(t1-t0)/(1000.*1000.));		<br />	<br />	[tableView reloadData];<br />	gettimeofday(&amp;tv,0);<br />	unsigned long long t2 = tv.tv_sec*1000*1000+tv.tv_usec;			<br />	NSLog(@&quot;reload data : %.3f&quot;,(t2-t1)/(1000.*1000.));	<br />}<br />		<br />- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView {<br />	return [model count];<br />}<br /><br />- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {<br />	return [[model objectAtIndex:rowIndex] valueForKey:[aTableColumn identifier]];<br />}<br /><br />-(IBAction) change :(id) sender {<br />	struct timeval tv;<br />	gettimeofday(&amp;tv,0);<br />	unsigned long long t0 = tv.tv_sec*1000*1000+tv.tv_usec;<br />	<br />	NSImage * image0=[NSImage imageNamed:@&quot;one&quot;];<br />	NSImage * image1=[NSImage imageNamed:@&quot;two&quot;];<br />	NSImage * image2=[NSImage imageNamed:@&quot;three&quot;];<br />	for(NSUInteger index=1955;index&lt;2009;index++) {<br />		NSDictionary * dict=<br />		[NSDictionary dictionaryWithObjectsAndKeys:<br />		 [NSString stringWithFormat:@&quot;Bidule %d&quot;,index],@&quot;firstColumn&quot;,<br />		 ((index%3==0)? image2 : (index%3==1)? image0 : image1 ) ,@&quot;secondColumn&quot;,<br />		 nil];<br />		[model replaceObjectAtIndex:index withObject:dict];<br />	}<br /><br />	gettimeofday(&amp;tv,0);<br />	unsigned long long t1 = tv.tv_sec*1000*1000+tv.tv_usec;			<br />	NSLog(@&quot;chargement : %.3f&quot;,(t1-t0)/(1000.*1000.));		<br />	<br />	<br />}<br />@end<br />
    

  • schlumschlum Membre
    02:48 modifié #7
    Le nombre d'éléments ne doit absolument pas jouer... Il ne charge que les nouveaux qu'il doit afficher lors d'un défilement.
Connectez-vous ou Inscrivez-vous pour répondre.