J'appelle une méthode qui va dans un fil de fond:Pourquoi n'y a-t-il pas de pool de libération automatique lorsque je fais performSelectorInBackground:?
[self performSelectorInBackground:@selector(loadViewControllerWithIndex:) withObject:[NSNumber numberWithInt:viewControllerIndex]];
, j'ai cette implémentation de la méthode qui est appelée par le sélecteur:
- (void) loadViewControllerWithIndex:(NSNumber *)indexNumberObj {
NSAutoreleasePool *arPool = [[NSAutoreleasePool alloc] init];
NSInteger vcIndex = [indexNumberObj intValue];
Class c;
UIViewController *controller = [viewControllers objectAtIndex:vcIndex];
switch (vcIndex) {
case 0:
c = [MyFirstViewController class];
break;
case 1:
c = [MySecondViewController class];
break;
default:
NSLog(@"unknown index for loading view controller: %d", vcIndex); // error
break;
}
if ((NSNull *)controller == [NSNull null]) {
controller = [[c alloc] initWithNib];
[viewControllers replaceObjectAtIndex:vcIndex withObject:controller];
[controller release];
}
if (controller.view.superview == nil) {
UIView *placeholderView = [viewControllerPlaceholderViews objectAtIndex:vcIndex];
[placeholderView addSubview:controller.view];
}
[arPool release];
}
Althoug Je ne crée une piscine autorelease il pour ce thread, je reçois toujours cette erreur:
2009-05-30 12:03:09.910 Demo[1827:3f03] *** _NSAutoreleaseNoPool(): Object 0x523e50 of class NSCFNumber autoreleased with no pool in place - just leaking
Stack: (0x95c83f0f 0x95b90442 0x28d3 0x2d42 0x95b96e0d 0x95b969b4 0x93a00155 0x93a00012)
Si j'ôterai la piscine autorelease, je reçois un tas de messages comme ceux-ci. J'ai également essayé de créer un pool autorelease autour de l'appel du performSelectorInBackground :, mais cela n'aide pas.
Je suspecte le paramètre, mais je ne sais pas pourquoi le compilateur se plaint d'un NSCFNumber. Est-ce que je manque quelque chose?
Mes variables d'instance sont toutes "non atomiques". Cela peut-il être un problème? MISE À JOUR: Je peux également soupçonner qu'une certaine variable a été ajoutée à un pool d'autorelease du thread principal (peut-être un ivar), et maintenant il essaie de libérer celui-ci dans le mauvais pool autorelease? Si oui, comment pourrais-je résoudre ce problème? (putain, ce truc de threading est complexe;))
Essayez la fixation d'un point d'arrêt sur _NSAutoreleaseNoPool pour voir d'où il est appelé depuis – rpetrich
Tangent question: ici un nouveau contrôleur, alloué localement dans ce thread, est ajouté à un tableau global et sa vue est ajoutée en sous-vue. Est-ce un problème dans la mesure où l'objet est créé dans un pool différent de son conteneur? –
@dk vous ne devriez pas poser une question tangente, posez une question séparée! Quoi qu'il en soit, je déconseille vivement de créer des objets liés à l'interface utilisateur (contrôleurs et vues) dans un thread non principal. C'est une catastrophe qui attend de se produire. – Yuji