2011-03-29 5 views
0

Une de mes classes personnalisées a NSThread * comme variable membre.(iphone) ayant NSThread * comme variable membre est une mauvaise idée?

Je laisse le thread quitter en définissant une variable (isNeedToExit).
Appelez ensuite une version sur l'objet thread [version myThread];

Je voulais que le thread sorte en premier et que l'appel de libération soit appelé.
Mais à la réflexion, l'appel de libération peut être appelé avant que le thread ne remarque la valeur booléenne et quitter.
(Parce que le thread ne regarde pas constamment la valeur pour voir s'il doit quitter)

@property (nonatomic, retain) NSThread * myThread;

- (void) dealloc 
{ 
    ... 
    [myThread release]; 
    myThread = nil; 
    ... 
    [super dealloc]; 
} 

- (id) initMyClass 
{ 
    if(self = [super init]) 
    { 
     ... 
     NSThread* aThread = [[NSThread alloc] initWithTarget: self selector:@selector(theThreadMain) object: nil]; 
     self.myThread = aThread; 
     [aThread release]; 
     [self.myThread start]; 
     .. 
    } 
    return self; 
} 

- (void) theThreadMain 
{ 
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 

    // Add your sources or timers to the run loop and do any other setup.                                         
    NSRunLoop *runloop = [NSRunLoop currentRunLoop]; 
    [runloop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; 

    do 
    { 
     // Start the run loop but return after each source is handled.                                          
     SInt32 result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, YES); 

    } 
    while (self.isNeedToExit == false); 

    [pool release]; 

    SYSLOG(LOG_DEBUG, "thread exiting"); 
} 

Je pensais que déplacer [version MyThread] appel (maintenant à la dealloc de classe) à la dernière ligne de theThreadMain ..

Je ne sais pas si cela est la bonne façon d'arrêter un fil quand il est un variable membre d'une autre classe.

Merci

Répondre

1

En fait, votre hypothèse de départ était plus correct. Votre implémentation actuelle, cependant, ne fonctionnera pas car dealloc ne sera jamais appelée.

Votre classe est conservée par NSThread dans initWithTarget:selector:object et ne sera pas libérée avant la fin de l'exécution du thread. Par conséquent, votre instance de classe ne sera pas libérée tant que le thread est en cours d'exécution. Une façon de résoudre le problème est d'ajouter une méthode "cancel" à votre classe qui arrête le thread. Par exemple:

- (void)cancel 
{ 
    isNeedToExit = YES; 
    [myThread release]; 
    myThread = nil; 
} 

Cela provoquera le fil pour arrêter et permettra à votre classe à désalloué (une fois le fil s'arrête.) Vous devez vous assurer que tous les utilisateurs de votre classe savent que « annuler » doit être appelé avant que la classe soit libérée. E.g .:

[myObject cancel]; // Stop the thread 
[myObject release]; 
myObject = nil; 

Une solution plus traditionnelle serait de simplement sous-classer NSThread.

+0

merci de répondre, si je vous ai bien compris, ma mise en œuvre actuelle (code ci-dessus) est très bien. Puisque ce que je fais est essentiellement, "myObject.isNeedToExit = YES; [myObject release];" , et lorsque le thread est terminé par l'indicateur isNeedToExit, il libère myObject une fois de plus et appelle dealloc. Ce qui appellera [myThread] finalement. Qu'est-ce que tu penses? – eugene

Questions connexes