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

3 に答える 3

2

それはデリゲートが機能する方法ではありません。

クラスインスタンスを別のインスタンスのデリゲートとして割り当てます。あなたの場合、クラスメソッドはインスタンスの一部ではない(静的である)ため、これは簡単ではありません。そのため、クラスのグローバルインスタンスを1つ生成するには、シングルトンを作成する必要があります(これはクラスメソッドを提供するのと同じです)。

これを行うには、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

フィリップミルズがコメントしたように、これは代表者の働き方ではありません。

次のようにクラスメソッドを変更することで、クイックフィックス(ダーティ)を実行できます。

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

そしてdelegate、クラスメソッドのパラメータを使用してaudioPlayerインスタンスに転送します

于 2012-11-05T16:02:27.150 に答える