2010-09-03 2 views
0

J'ai une méthode de classe C++ où j'ai besoin d'appeler la méthode "detachNewThreadSelector" avec tous les paramètres.
Ici se trouve le problème, car ma classe n'est pas objective C je n'ai pas de pointeur auto. Aussi je ne vois pas comment je serai capable d'appeler une méthode de classe à partir de la méthode que je définirai comme sélecteur.
S'il vous plaît demandez si ma question n'est pas claire, je ne suis pas d'un pays anglophone.
Voici du code.iPhoneOS: utilisation de la méthode detachNewThreadSelector dans une méthode de classe C++

ALuint AudioController::PlayStream(const string& asset) 
{ 
     //attach to a thread 
    [NSThread detachNewThreadSelector:(SEL)selector  toTarget:(id)selfwithObject:(id)argument] 

} 

void AudioController::RotateThread(const string& soundKey) 
{ 
} 

Comme vous pouvez voir comment passer je ne la méthode RotateThread comme un sélecteur à « detachNewThreadSelector » et aussi où puis-je obtenir le pointeur auto.

Toute aide très appréciée.
Merci

Répondre

0

vous ne pouvez pas utiliser l'objet C++ de cette manière (en tant qu'argument de cette méthode NSThread). Si votre cas est simple (lisez: peu d'interfaces déclarées), vous pouvez créer une classe utilitaire (objc) pour gérer le message, puis renvoyer l'argument à l'instance AudioController. Illustration:

(code pseudo non compilé suit)

namespace pseudo_object { 
template <typename> class reference_counted; 
} 

@interface MONAudioControllerWorker : NSObject 
{ 
    pseudo_object::reference_counted<AudioController> audioController_; 
    std::string asset_; 
} 

+ (MONAudioControllerWorker *)newMONAudioControllerWorkerWithAudioController:(pseudo_object::reference_counted<AudioController>&)audioController asset:(const std::string&)asset; 
- (void)secondaryWorker; 

@end 

@implementation MONAudioControllerWorker 

+ (MONAudioControllerWorker *)newMONAudioControllerWorkerWithAudioController:(pseudo_object::reference_counted<AudioController>&)audioController asset:(const std::string&)asset 
{ 
/* ... */ 
} 

- (void)secondaryWorker 
{ 
    NSAutoreleasePool * pool([NSAutoreleasePool new]); 
    audioController_->RotateThread(asset_); 
    [pool release]; 
} 

@end 
/* static */ 
ALuint AudioController::PlayStream(pseudo_object::reference_counted<AudioController>& This, const string& asset) 
{ 
/* attach to a thread */ 
    MONAudioControllerWorker * controller = [MONAudioControllerWorker newMONAudioControllerWorkerWithAudioController:This asset:asset]; 
    [NSThread detachNewThreadSelector:@selector(secondaryWorker) toTarget:controller withObject:0]; 
    [controller release]; 
} 

parfois, il est plus facile de créer une classe objc qui peut contenir une version simplifiée interface (générique) à cet effet (par exemple réutilisable au-delà de cet objet) ou pour utiliser des routines de threading plus traditionnelles (pthreads). Si c'est le seul cas dans le projet, alors ça devrait aller. Sinon, vous vous retrouvez avec de nombreuses classes/symboles utilitaires et beaucoup plus à entretenir. illustration:

@interface MONAudioControllerWrapper : NSObject 
{ 
    AudioController audioController_; 
    std::string asset_; 
} 

+ (MONAudioControllerWrapper *)newMONAudioControllerWrapperWithAsset:(const std::string&)asset; 

- (void)playStream; 

@end 

@implementation MONAudioControllerWrapper 

+ (MONAudioControllerWrapper *)newMONAudioControllerWrapperWithAsset:(const std::string&)asset 
{ 
/* ... */ 
} 

- (void)secondaryWorker 
{ 
    NSAutoreleasePool * pool([NSAutoreleasePool new]); 
    audioController_->RotateThread(asset_); 
    [pool release]; 
} 

- (void)playStream 
{ 
    [NSThread detachNewThreadSelector:@selector(secondaryWorker) toTarget:self withObject:0]; 
} 

@end 
+0

Merci pour la réponse rapide justin. Je vais essayer ça. Ça a l'air assez compliqué. –

+0

de rien. Si vous avez besoin de 2 classes (comme dans le cas ci-dessus), il est * souvent * plus facile de mettre l'objet cpp en ivar d'un objet objc. – justin

+0

Est-ce que vous sous-entendez que j'ai un objc global et que je l'utilise pour accéder aux objets cpp. –

1

Vous ne pouvez pas faire cela. Ce n'est pas aussi simple que "Où puis-je obtenir le pointeur auto?" La vraie question est, "Où puis-je obtenir quelque chose qui peut répondre aux messages?" Car une classe C++ ne peut pas.

Les classes, les objets et les méthodes Objective-C sont complètement différents des classes, des objets et des méthodes C++. Le fait que les deux langues utilisent la même terminologie et utilise les choses à des fins similaires déroute beaucoup de gens, mais pour être clair: ce sont des choses totalement différentes qui fonctionnent de manière très différente dans les deux langues. Exemple: les méthodes C++ sont simplement appelées plutôt que distribuées en fonction d'un sélecteur comme les méthodes Objective-C. Et les classes C++ ne sont même pas des objets.

Vous avez deux options réelles ici:

  1. Créer une classe Objective-C qui a le comportement que vous voulez.

  2. Utilisez une solution concurrente C++.

+0

Pouvez-vous s'il vous plaît fournir un extrait mettant en œuvre la solution d'accès concurrentiel C++. Beaucoup intéressé d'apprendre à ce sujet. merci –

+0

@John M: Ce n'est pas vraiment mon fort, mais voici un exemple que j'ai trouvé sur Stack Overflow: http://antonym.org/2009/05/threading-with-boost---part-i-creating-threads. html – Chuck

0

Comme d'autres l'ont déjà dit, on ne peut pas utiliser detachThreadWithSelector: faire passer un objet en C++ en tant que cible ou en utilisant un procédé de C++ en tant que sélecteur.

Vous avez deux stratégies:

  1. envelopper l'objet et le sélecteur avec un objet Objective-C et sélecteur par exemple

    myAudioControllerWrapper = [[OCAudioControllerWrapper alloc] initWithRealController: this]; 
    // need some code to release once thread is complete 
    [NSThread detachNewThreadSelector: @selector(wrapperSelector:) target: myAudioControllerWrapper withObject: soundKeyAsNSObject]; 
    

    et votre sélecteur d'emballage ressemble:

    -(void) wrapperSelector: (id) key 
    { 
        cppController->rotateThread([key cppObject]); 
    } 
    
  2. Utilisez un autre mécanisme de fil plus conforme au paradigme C++. Grand Central Dispatch peut être le seul si votre plate-forme le prend en charge.

Questions connexes