如何将委托设置为类方法

时间:2012-11-05 15:47:53

标签: iphone ios avfoundation avaudioplayer

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 common

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

3 个答案:

答案 0 :(得分:2)

这不是代表的工作方式。

您将一个类实例指定为另一个实例的委托。现在在你的情况下,这并不容易,因为类方法不是实例的一部分(它是静态的)。因此,您需要创建一个Singleton,以便为您的类生成一个全局实例(这相当于提供类方法)。

为此,请将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 

{{1}}

在我看来,将单身人士作为某事物的代表并不是很好的设计。在回答您的原始问题时,不,您不能将类方法指定为单个委托,您只能设置整个类的实例。我强烈建议你阅读委托如何运作: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/CommunicateWithObjects.html#//apple_ref/doc/uid/TP40002974-CH7-SW18

答案 1 :(得分:0)

您最好的选择是使用实例方法并创建属于您的common类的实际对象,然后使用self作为代理。

(从技术上讲,你可能能够使用当前代码和[audioPlayer setDelegate:(id<AVAudioPlayerDelegate>)[self class]];来触发类方法,但即使它有效也不是一个好主意。)

答案 2 :(得分:0)

像菲利普米尔斯评论的那样,这不是代表的工作方式。

您可以通过更改类方法来执行quickfix(dirty):

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

并使用类方法中的delegate参数将其转发到audioPlayer实例