iPhoneOS: использование метода detachNewThreadSelector внутри метода класса C ++ - PullRequest
0 голосов
/ 03 сентября 2010

У меня есть метод класса C ++, где мне нужно вызвать метод detachNewThreadSelector со всеми параметрами.
Здесь кроется проблема, поскольку мой класс не является объективным C, у меня нет указателя self.Также я не понимаю, как я смогу вызвать метод класса из метода, который я установлю в качестве селектора.
Пожалуйста, спросите, если мой вопрос не ясен, я не из англоговорящей страны.
Вот некоторый код.

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», а также где я могу получить собственный указатель.

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

Ответы [ 3 ]

1 голос
/ 03 сентября 2010

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

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

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

  1. Создайте класс Objective-C с нужным вам поведением.

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

0 голосов
/ 03 сентября 2010

Как уже говорили другие, вы не можете использовать 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 может быть тем, если ваша платформа поддерживает его.

0 голосов
/ 03 сентября 2010

вы не можете использовать объект 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
...