2010-09-03 2 views
0

У меня есть метод класса C++, где мне нужно вызвать метод detachNewThreadSelector со всеми параметрами.
Здесь проблема, так как мой класс не объективен. У меня нет указателя на себя. Также я не вижу, как я могу вызвать метод класса из метода, который я установлю как селектор.
Пожалуйста, спросите, не мой ли вопрос, я не из англоговорящей страны.
Вот несколько кодов.iPhoneOS: использование метода detachNewThreadSelector внутри метода класса 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) 
{ 
} 

Как вы можете видеть, как я прохожу метод RotateThread как селектор в «detachNewThreadSelector», а также, где я могу получить указатель сам.

Любая помощь очень ценится.
Спасибо

ответ

0

вы не можете использовать объект C++ таким образом (в качестве аргумента для этого метода NSThread). если ваш случай прост (читайте: несколько объявленных интерфейсов), вы можете создать класс утилиты (objc) для обработки сообщения и затем передать аргумент обратно в экземпляр AudioController. иллюстрации:

(не скомпилированный код псевдо следующим образом)

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]; 
} 

иногда это просто легче создать ObjC класс, который может содержать упрощенную (общий) интерфейс для этой цели (т.е. многократного использования за пределами этого объекта) , или для использования более традиционных подпрограмм потоков (pthreads). если это единственный случай в проекте, то это должно быть хорошо. в противном случае вы получаете множество полезных классов/символов и многое другое для поддержки. Иллюстрация:

@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

Спасибо за быстрый ответ justin. Я попробую это. Выглядит довольно сложно. –

+0

добро пожаловать. если вам нужно 2 класса (как в приведенном выше случае), то * часто * проще поставить объект cpp как ivar объекта objc. – justin

+0

Вы подразумеваете, что у меня есть глобальный объект objc и используйте его для доступа к объектам cpp. –

1

Вы не можете сделать этого. Это не так просто, как «Где я могу получить указатель на себя?» Фактический вопрос: «Где я могу получить что-то, что может реагировать на сообщения?» Потому что класс C++ не может.

Objective-C классы, объекты и методы - это совершенно разные вещи из классов, объектов и методов C++. Тот факт, что эти два языка используют одну и ту же терминологию и использует вещи для аналогичных целей, смущает много людей, но для того, чтобы быть ясным: они совершенно разные вещи, которые работают по-разному на двух языках. Дело в том, что методы C++ просто вызывают, а не отправляются на основе селектора типа Objective-C. А классы C++ - это даже не объекты.

У вас есть два реальных варианта здесь:

  1. Создать класс Objective-C, который имеет поведение, которое вы хотите.

  2. Используйте решение параллелизма на C++.

+0

Можете ли вы предоставить фрагмент, реализующий решение параллелизма на C++. Очень интересно узнать об этом. спасибо –

+0

@John M: Это не моя сильная сторона, но вот пример, который я нашел в Stack Overflow: http://antonym.org/2009/05/threading-with-boost---part-i-creating-threads. HTML – Chuck

0

Как уже говорили другие, вы не можете использовать detachThreadWithSelector: передавая объект C++ в качестве мишени или с использованием метода C++ в качестве селектора.

У Вас есть две стратегии:

  1. обернуть объект и селектор с объектом Objective-C и селектор, например

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

    и ваш селектор обертка выглядит следующим образом:

    -(void) wrapperSelector: (id) key 
    { 
        cppController->rotateThread([key cppObject]); 
    } 
    
  2. Используйте какой-либо другой механизм резьбы больше в соответствии с парадигмой C++. Grand Central Dispatch может быть единственным, если ваша платформа поддерживает его.

Смежные вопросы