2010-09-03 58 views
0

我有一個C++類方法,我需要用所有參數調用「detachNewThreadSelector」方法。
這裏存在的問題,因爲我的類不客觀C我沒有自己的指針。另外我不明白我將如何能夠從我將設置爲選擇器的方法中調用類方法。
請問如果我的問題不清楚,我不是來自講英語的國家。
這是一些代碼。iPhoneOS:在C++類中使用detachNewThreadSelector方法

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類(即重複使用的超出此目的) ,或者使用更傳統的線程例程(pthread)。如果這是該項目中唯一的情況,那麼它應該沒問題。否則,你最終會得到許多實用程序類/符號和更多的維護。插圖:

@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

感謝您的快速回復賈斯汀。我會試試看。看起來相當複雜。 – 2010-09-03 07:42:38

+0

不客氣。如果你需要2個類(就像在上面的例子中那樣),它通常很容易把cpp對象作爲一個objc對象的ivar。 – justin 2010-09-03 07:47:15

+0

您是否暗示我有一個全局objc對象並使用它來訪問cpp對象。 – 2010-09-03 08:01:16

1

你不能這樣做。它不像「我在哪裏得到自己的指針?」那樣簡單?實際的問題是,「我在哪裏可以得到可以回覆消息的東西?」因爲一個C++類不能。 Objective-C類,對象和方法與C++類,對象和方法完全不同。兩種語言使用相同的術語並將這些東西用於類似目的的事實使很多人感到困惑,但要清楚:在兩種語言中,它們是完全不同的,以完全不同的方式工作的東西。例如:C++方法只是簡單地調用,而不是像Objective-C方法那樣根據選擇器調度。而C++類甚至不是對象。

您這裏有兩個真正的選擇:

  1. 創建有你想要的行爲的Objective-C類。

  2. 使用C++併發解決方案。

+0

您能否提供一個實現C++併發解決方案的代碼片段?非常有興趣瞭解它。謝謝 – 2010-09-03 07:51:15

+0

@John M:這不是我的特長,但這裏是我在Stack Overflow上找到的一個例子:http://antonym.org/2009/05/threading-with-boost---part-i-creating-threads。 HTML – Chuck 2010-09-03 07:57:59

0

正如其他人所說的,你不能使用detachThreadWithSelector:傳遞一個C++對象作爲目標或使用C++方法作爲選擇器。

有兩種策略:

  1. 包裹以客觀-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