目标C协议方法未被调用

时间:2015-03-10 04:48:16

标签: objective-c singleton protocols avaudioplayer

我为AVAudioPlayer创建了单例类。我可以调用类中的方法,一切正常。当歌曲结束时,调用方法(void)audioPlayerDidFinishPlaying,然后调用我的downloadPlay.m类中的方法'processSuccessful'。但是,它没有调用方法'processSuccessful'

我的代码如下

PlayerManager.h 

#import <Foundation/Foundation.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>

@protocol ProcessDataDelegate <NSObject>
@required
- (void) processSuccessful;
@end

@interface PlayerManager : NSObject<AVAudioPlayerDelegate,AVAudioSessionDelegate>
{
 id <ProcessDataDelegate> delegate;
}
+ (PlayerManager *)sharedAudioPlayer;
@property (nonatomic,assign) id <ProcessDataDelegate>delegate;
@property (nonatomic, strong) AVAudioPlayer* player;
-(void)preparesong:(NSURL *)url;
-(void)stopsong;
-(void)pause;
-(void)playsong;
-(void)prepareToPlay;
-(BOOL)isPlaying;
-(BOOL)isPlayerExist;
@end

PlayerManager.m

#import "PlayerManager.h"

@interface PlayerManager()
@end

@implementation PlayerManager
@synthesize player;
@synthesize delegate;

static PlayerManager *sharedAudioPlayer = nil;
+ (PlayerManager *)sharedAudioPlayer {
    static PlayerManager *sharedAudioPlayer = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedAudioPlayer = [[self alloc] init];
    });
    return sharedAudioPlayer   ;
}

- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player withOptions:(NSUInteger)flags
{

    if (flags & AVAudioSessionInterruptionOptionShouldResume)
    {
    [self.player play];

    }
}
- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player
{

}
#pragma mark - AVAudioPlayerDelegate
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
    [[self delegate] processSuccessful];
}

- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error
{

}

-(void)preparesong:(NSURL *)url
{
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    NSError *error;
    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url  error:&error];
    if(!self.player)
    {
        NSLog(@"Error creating player: %@", error);
    }
    self.player.delegate = self;
    [self.player prepareToPlay];

}
-(BOOL)isPlayerExist
{
    if (player)
        return YES;
    return NO;

}
-(BOOL)isPlaying
{
    if (player && player.playing)
        return YES;
    return NO;

}
-(void)prepareToPlay
{
    if (player)
        [self.player prepareToPlay];
}
-(void)playsong
{
    if (player)
        [self.player play];

}
-(void)pause
{
    if (player.playing)
        [self.player pause];

}
-(void)stopsong
{
    if (player)
    [self.player stop];
}
@end

downloadPlay.h

#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#import "PlayerManager.h"
@interface downloadPlay: UIViewController <UITableViewDelegate,AVAudioPlayerDelegate,ProcessDataDelegate>
{
    PlayerManager *protocolPlay;
}

@property (retain, nonatomic) IBOutlet UITableView *tblFiles;
......
- (void)startPlay:(id)sender;

........
@end

downloadPlay.m

import "downloadPlay.h"
#import "PlayerManager.h"

@interface downloadPlay ()

@end

@implementation downloadPlay
.....

- (void)processSuccessful
{
    NSLog(@"This method suppose to be called from the method audioPlayerDidFinishPlaying - from PlayerManager");
}

- (void)viewDidLoad
{

    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    protocolPlay = [[PlayerManager alloc]init];
    [protocolPlay setDelegate:self];

}

- (void)startPlay
{
    ............
    .........
    NSURL *destinationURL = [self.docDirectoryURL URLByAppendingPathComponent:filename];
    NSError* error = nil;
   [[PlayerManager sharedAudioPlayer]stopsong];
    [[PlayerManager  sharedAudioPlayer ] preparesong:destinationURL    ];
    [[PlayerManager sharedAudioPlayer]playsong];
}

@end

1 个答案:

答案 0 :(得分:2)

viewDidLoad方法中,您使用

创建不同的对象
protocolPlay = [[PlayerManager alloc]init]; 

行并设置此对象的委托,同时必须设置共享对象的委托。

解决方案是:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [[PlayerManager sharedAudioPlayer] setDelegate:self];
}