J'ai une classe dérivée de NSThread
:Objet NSThread conservé deux fois?
@interface FSEventMonitorThread : NSThread {
FSEventStreamRef m_fseStreamRef;
CFRunLoopRef m_runLoop;
}
- (id) initWithStream:
(FSEventStreamRef)fseStreamRef;
- (void) dealloc;
- (void) main;
@end
@implementation FSEventMonitorThread
- (id) initWithStream:
(FSEventStreamRef)fseStreamRef
{
if (self = [super init])
m_fseStreamRef = fseStreamRef;
return self;
}
- (void) dealloc
{
CFRunLoopStop(m_runLoop);
FSEventStreamStop(m_fseStreamRef);
[super dealloc];
}
- (void) main
{
m_runLoop = CFRunLoopGetCurrent();
FSEventStreamScheduleWithRunLoop(
m_fseStreamRef, m_runLoop, kCFRunLoopDefaultMode
);
FSEventStreamStart(m_fseStreamRef);
CFRunLoopRun();
}
@end
Ailleurs (dans une fonction C++), je crée une instance:
m_thread = [[FSEventMonitorThread alloc] initWithStream:m_fseStreamRef];
Ma compréhension est que le retenir comptage doit maintenant être 1. Dans une autre fonction C++, je veux arrêter et désaffecter le fil:
[m_thread release];
Pourtant, leLa méthoden'est pas appelée. Si je place:
[m_thread release];
[m_thread release];
alors dealloc
est appelé ce qui implique le retenir comptage était 2. Mais comment est-elle d'être 2?
Notez que la documentation pour NSThread
mentionne uniquement la conservation lors de l'utilisation de detachNewThreadSelector:toTarget:withObject:
.
CFRunLoopRun() ne retourne pas avant CFRunLoopStop() est appelée; par conséquent, mon main() ne peut pas vérifier isCancelled. J'ai passé outre la méthode cancel pour appeler CFRunLoopStop(). Donc maintenant, pour arrêter le thread, je fais [m_thread cancel] suivi de [m_thread release] et ça marche. Question: est-ce que la méthode annuler est une chose OK à faire? La documentation ne dit pas que l'on ne devrait pas. –
Cela dépend de ce que vous faites, mais en général, je dirais non, ne faites pas cela. Le moyen le plus simple de le faire serait d'ajouter une méthode comme finishThread; Je vais ajouter un exemple rapide à ma réponse. Vous devriez également faire le nettoyage dont vous avez besoin après le retour de la fonction CFRunLoopRun(). –