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

@实现常见

AVAudioPlayer* 音频播放器;

// 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
4

3 回答 3

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 

在我看来,让单例作为某事的代表并不是很好的设计。但是,在回答您最初的问题时,不,您不能将类方法分配为单独的委托,您只能设置整个类的实例。我强烈建议您阅读委托的工作原理:http: //developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/CommunicateWithObjects.html#//apple_ref/doc/uid/ TP40002974-CH7-SW18

于 2012-11-05T15:52:01.570 回答
0

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

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

于 2012-11-05T15:59:42.093 回答
0

正如 Philip Mills 所说,这不是代表的工作方式。

您可以通过更改类方法来执行快速修复(脏),如下所示:

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

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

于 2012-11-05T16:02:27.150 回答