LoadingView, initWithNibName, autoreleasePool, NSThred

muqaddarmuqaddar Administrateur
18:30 modifié dans API UIKit #1
Salut,

Dans un UIViewController, lorsque je clique sur un bouton, j'envoie une requete qui prend 3 ou 4 secondes, avant de charger un autre NIB du navigation Controller.

Pour faire patienter l'utilisateur, je charge une UIView avec un loading avant de charger le Nib.

Cette vue "loading" est chargée dans un nouveau thread, sinon elle s'efface de suite. Du coup, j'ai ce message d'erreur (que je comprends), dans ma console :

_NSAutoreleaseNoPool(): Object 0x156270 of class UITableView autoreleased with no pool in place - just leaking
Stack: (0x306d1c87 0x3066ebbb 0x3066eb87 0x30acbd80 0xf30f 0x30672e09 0x30672cd7 0x3146178d)
2009-06-05 11:53:16.995[2010:8007] *** _NSAutoreleaseNoPool(): Object 0x177410 of class LoadingView autoreleased with no pool in place - just leaking
Stack: (0x306d1c87 0x3066ebbb 0x3066eb87 0x1025f 0xf31b 0x30672e09 0x30672cd7 0x3146178d)
2009-06-05 11:53:17.052[2010:8007] *** _NSAutoreleaseNoPool(): Object 0x15ecc0 of class UINavigationButton autoreleased with no pool in place - just leaking
Stack: (0x306d1c87 0x3066ebbb 0x3066eb87 0x30bb9a3c 0x30a548e4 0x302613d5 0x30a5494c 0x30a736fc 0x30a77218 0x30a77070 0x30a70c1c 0x102c9 0xf31b 0x30672e09 0x30672cd7 0x3146178d)
2009-06-05 11:53:17.065[2010:8007] *** _NSAutoreleaseNoPool(): Object 0x123e50 of class UICFFont autoreleased with no pool in place - just leaking
Stack: (0x306d1c87 0x3066ebbb 0x3066eb87 0x30ba4374 0x30b51568 0x30b515d4 0x30b51758 0x10337 0xf31b 0x30672e09 0x30672cd7 0x3146178d)
2009-06-05 11:53:17.080[2010:8007] *** _NSAutoreleaseNoPool(): Object 0x177600 of class UILabel autoreleased with no pool in place - just leaking
Stack: (0x306d1c87 0x3066ebbb 0x3066eb87 0x10349 0xf31b 0x30672e09 0x30672cd7 0x3146178d)
2009-06-05 11:53:17.100[2010:8007] *** _NSAutoreleaseNoPool(): Object 0x24a14 of class NSCFString autoreleased with no pool in place - just leaking


Donc pas de plantage, mais une belle fuite mémoire lorsque je charge et push ma view suivante...

Voici mon code :

- (IBAction)searchByList:(id)sender {<br />	// show a loading message<br />	[NSThread detachNewThreadSelector:@selector(startLoading) toTarget:self withObject:nil];<br />	<br />	// preferences<br />	NSArray *array = [[NSUserDefaults standardUserDefaults] objectForKey:@&quot;mykey&quot;];	<br />	NSArray *results = [MyClass findObjectsWithsList:array];<br />		<br />	// send results to search results controller<br />	SearchResultsTableViewController *searchResultsTableViewController;<br />	searchResultsTableViewController = [[SearchResultsTableViewController alloc] initWithNibName:@&quot;SearchResultsTableView&quot; bundle:nil];<br />	[searchResultsTableViewController set_results:results];<br />	<br />	// push view controller<br />	[[self navigationController] pushViewController:searchResultsTableViewController animated:YES];<br />	[searchResultsTableViewController release];	<br />}<br /><br />- (void)startLoading {<br />	_loadingView = [LoadingView loadingViewInView:self.view];	<br />	[NSThread exit];<br />}


Ce que je ne comprends pas, c'est que le initiWithNibName ne soit plus dans le thread principal et dans l'autorelease pool de l'appli. Il n'y a que la vue loading qui est chargée dans un thread secondaire pourtant.

Si je vire mes threads, plus de problème, mais la vue loading s'affiche 1/4 de seconde au lieu de 4... Donc ce qui prend du temps, est effectué avant l'affichage de la vue loading (pourtant chargée avant par le code)... ce qui n'a plus d'intérêt.

Quels sont vos conseils ?

Réponses

  • AliGatorAliGator Membre, Modérateur
    juin 2009 modifié #2
    Il faut créer ton NSAutoreleasePool. Il n'y a que le mainThread qui la crée tout seul.

    Donc dans ta méthode main de ton NSThread, ou dans ton @selector que tu fais exécuter quand tu lances ton thread quoi, il faut commencer par [tt]NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];[/tt] et terminer à  la fin de ta méthode par [tt][pool release];[/tt].

    For non garbage-collected applications, the method aSelector is responsible for setting up an autorelease pool for the newly detached thread and freeing that pool before it exits. Garbage-collected applications do not need to create an autorelease pool.


    Toutes les infos ici, dans le Threading Programming Guide
  • muqaddarmuqaddar Administrateur
    18:30 modifié #3
    Ah, je n'étais pas loin... j'avais créé un autorelease pool mais je l'avais mis dans la méthode principale et pas dans la méthode de thread.

    Là , ça marche. Merci Ali.
    Encore flou pour moi le fonctionnement de ces threads.
Connectez-vous ou Inscrivez-vous pour répondre.