2012-11-05 22 views
1

代表AVAudioPlayer可以設置爲班級成員audioPlayerDidFinishPlaying如何將代表設置爲班級方法

我想使用類方法播放聲音文件,但無法弄清楚如何將setDelegate:設置爲audioPlayerDidFinishPlaying類方法。

我有一個叫做'common'的小類,只有靜態成員。

請參見下面的 '< < < <' 標誌......

@class common; 

@interface common : NSObject <AVAudioPlayerDelegate> { 
} 
    +(void) play_AV_sound_file: (NSString *) sound_file_m4a; 
    +(void) audioPlayerDidFinishPlaying: (AVAudioPlayer *) player successfully: (BOOL) flag 
@end 

@implementation共同

AVAudioPlayer * audioPlayer;

// Starts playing sound_file_m4a in the background. 
+(void) play_AV_sound_file: (NSString *) sound_file_m4a 
{ 
    printf("\n play_AV_sound_file '%s' ", [sound_file_m4a UTF8String]); 

    NSString *soundPath = [[NSBundle mainBundle] pathForResource:sound_file_m4a ofType:@"m4a"]; 
    NSError *error; 
    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath: soundPath] error:&error ]; 

    [audioPlayer setDelegate:audioPlayerDidFinishPlaying];  //<<<<<<<<<< causes error 
        >>> what should setDelegate: be set to? <<< 


    [audioPlayer prepareToPlay]; 
    [audioPlayer play]; 
} 


+(void) audioPlayerDidFinishPlaying: (AVAudioPlayer *) player successfully: (BOOL) flag 
{ 
    printf("\n audioPlayerDidFinishPlaying"); 

    [audioPlayer release]; 
    audioPlayer=nil; 
    [audioPlayer setDelegate:nil];  
} 

@end 

回答

2

這不是代表們的工作方式。

指定一個類實例作爲另一個實例的委託。現在在你的情況下,這並不容易,因爲類方法不是實例的一部分(它是靜態的)。因此,您需要創建一個單例,以便爲您的類生成一個全局實例(這相當於提供類方法)。

,通過提供這是你唯一的類方法做到這一點,讓common單身:

static common* singleCommon = nil; 
+(common*) sharedInstance { 
    @synchronized(singleCommon) { 
     if(!singleCommon) { 
      singleCommon = [[common alloc] init]; 
     } 
    } 

    return singleCommon; 
} 

從此在,在你的榜樣,你會使用。

[audioPlayer setDelegate:[common sharedInstance]]; 

在這樣做時,你需要確保你的common類(理想情況下應該有一個資本C),有一個實例方法,下面的AVAudioPlayDelegate協議(這由它的外觀,它爲類方法)。你需要改變

+(void) audioPlayerDidFinishPlaying: (AVAudioPlayer *) player successfully: (BOOL) flag 

-(void) audioPlayerDidFinishPlaying: (AVAudioPlayer *) player successfully: (BOOL) flag 

在我看來,有一個單獨的東西委託是不是偉大的設計。儘管如此,在回答你最初的問題時,不,你不能將類方法指定爲單獨的委託,你只能設置整個類的實例。我強烈建議你對代表團的工作方式讀了起來: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/CommunicateWithObjects.html#//apple_ref/doc/uid/TP40002974-CH7-SW18

0

你最好的選擇是使用實例方法和創建和屬於您common類實際的對象,然後用self作爲代表。

(從技術上講,你也許可以與您當前的代碼和[audioPlayer setDelegate:(id<AVAudioPlayerDelegate>)[self class]];閃避觸發類的方法,但它不是真的,即使它的工作原理是個好主意。)

0

像菲利普米爾斯評論說,這是而不是代表如何工作。

你可以通過改變類方法,像這樣進行的quickfix(髒):

+(void) play_AV_sound_file:(NSString *)sound_file_m4a withDelegate:(id<AVAudioPlayerDelegate>)delegate; 

,並使用delegate參數在類中的方法將其轉發給您的audioPlayer實例