1

je la méthode suivante qui est engendré par un appel à un nouveau thread (en utilisant NSThread):Fidéliser un objet créé dans un NSThread

- (void) updateFMLs { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSArray *temp = [[NSArray alloc] initWithArray:someArrayFromAnotherProcess]; 

    [self performSelectorOnMainThread:@selector(doneLoading:) withObject:temp waitUntilDone:NO]; 
    [pool release]; 
} 

Ma méthode doneLoading: ressemble à ceci:

- (void) doneLoading:(NSArray *)obj { 
    myArray = [[NSArray alloc] initWithArray:obj copyItems:NO]; 
} 

Le contenu de myArray n'est plus valide. Comment puis-je conserver le contenu de myArray afin de pouvoir les utiliser plus tard dans mon application?

P.S. myArray est défini dans le fichier d'en-tête de classe.

+0

Qu'entendez-vous par "devenir invalide". Sont-ils désaffectés? –

+1

BTW, vous fuyez le tableau "temp". Vous allouez un tableau (+1 retain count), mais vous ne le libérez jamais. –

+0

oui ils semblent être désaffectés pendant que je progresse dans doneLoading ... même si rien dans doneLoading, sauf pour la ligne montrée ci-dessus, altère myArray en aucune façon – zpesk

Répondre

0

Le code que vous avez publié semble correct, à l'exception de la fuite de mémoire dans updateFMLs. Vous surestimez probablement les objets ailleurs. Je devine que ce serait partout où someArrayFromAnotherProcess est faite.

+0

Lorsque je débogue updateFMLs - temp est rempli avec les données correctes. Quand il est passé à doneLoading et devient invalide, c'est ce qui me gâche ... – zpesk

+1

Ils peuvent être désalloués lorsque le pool est libéré dans updateFMLs, ce qui arrivera avant que doneLoading ne soit appelé. –

+0

C'est ce que je pensais. Comment est-ce que je réparerais ceci ??? – zpesk

1

Si votre fil d'arrière-plan fait un travail et doit « passer » un NSArray à votre thread principal, alors tout doneLoading doit faire est:

-(void)doneLoading:(NSArray *)obj 
{ 
    [myArray release]; // release the previous array and its objects 
    myArray = [obj retain]; 
    // now use myArray, refresh tables, etc. 
} 

Il y a (probablement) pas besoin de faire une autre copie le tableau, et cela pourrait être le problème sous-jacent. Vous devez également appeler [temp release] après votre appel performSelector, car les arguments sont déjà conservés.

Si le contenu de myArray est en train de devenir valide d'une manière ou d'une autre, alors ils sont doublement libérés quelque part. myArray conservera tous les objets qui y sont ajoutés. Vous avez mentionné que myArray lui-même devient invalide, alors essayez de réécrire votre thread d'arrière-plan et votre méthode doneLoading avec ce modèle.

Enfin, vous devez utiliser [pool drain] au lieu de [pool release].

+0

Que se passe-t-il si l'autre thread utilise 'myArray' entre votre message' release' et l'assignation du nouveau tableau? –

+0

Probablement (basé sur la question) il utilise 'myArray' sur le thread principal seulement. Il semble que son thread d'arrière-plan configure un nouveau modèle et doit ensuite le transmettre au thread principal pour le traitement. Sa question concerne plus la gestion de la mémoire que la synchronisation des threads. Pour résoudre le problème que vous soulevez, il doit ajouter des blocs @synchronized (self) {}. De plus, 'updateFMLs' se ferme immédiatement après' doneLoading'. – Jason

0

Une alternative aux options serait au-dessus de déclarer monTableau comme une propriété atomique dans l'en-tête

@property (atomic,retain) NSArray *myArray; 

Puis, en updateFMLs vous devriez être en mesure d'appeler simplement le poseur du thread secondaire. Évidemment, cela ne fonctionne que si vous êtes prêt à payer la pénalité de performance pour une propriété atomique.

- (void) updateFMLs { 
    NSAutoreleasePool *pool - [[NSAutoreleasePool alloc] init]; 
    NSArray *temp = [[NSArray alloc] initWithArray:someArrayFromAnotherProcess]; 
    [self setMyArray:temp]; 
    [temp release]; 
    [pool drain]; 
} 
Questions connexes