iPhoneOS:在C ++类方法中使用detachNewThreadSelector方法

时间:2010-09-03 07:09:01

标签: c++ objective-c wrapper

我有一个C ++类方法,我需要用所有参数调用“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”,以及我在哪里获得自指针。

任何帮助都非常感谢。
感谢

3 个答案:

答案 0 :(得分:1)

你不能这样做。它不是一个简单的“我在哪里得到自我指针?”实际的问题是,“我从哪里获得能够响应消息的内容?”因为C ++类不能

Objective-C类,对象和方法与C ++类,对象和方法完全不同。这两种语言使用相同的术语并将其用于类似目的的事实让很多人感到困惑,但要明确:它们是完全不同的东西,在两种语言中以不同的方式工作。举个例子:简单地调用C ++方法而不是基于像Objective-C方法这样的选择器调度。而且C ++类甚至都不是对象。

这里有两个真正的选择:

  1. 创建一个具有所需行为的Objective-C类。

  2. 使用C ++并发解决方案。

答案 1 :(得分: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

答案 2 :(得分: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可能就是那个。