我在AVAudioPlayer上使用单例,效果很好。
我希望在初始化播放器之前添加一个检查,并在播放器已播放的情况下停止播放。
我添加了这段代码:
SoundPlayer *player = [SoundPlayer sharedInstance];
if([player isPlaying]){
[player stop];
}
但是它在if([player isPlaying])
行上给了我一个EXE_BAD_ACCESS。
2个问题:
这是完整的代码
#import "SoundPlayer.h"
@implementation SoundPlayer
@synthesize helpMode;
static SoundPlayer *sharedInstance = nil;
+ (SoundPlayer *)sharedInstance {
if (sharedInstance == nil) {
sharedInstance = [[super allocWithZone:NULL] init];
}
return sharedInstance;
}
+(BOOL)playSound:(NSURL*)url{
NSError *error;
SoundPlayer *player = [SoundPlayer sharedInstance];
if([player isPlaying]){
[player stop];
}
player = [[SoundPlayer sharedInstance] initWithContentsOfURL:url error:&error];
[player play];
if (player == nil){
NSLog(@"error %@ \n for file %@",[error description],[url path]);
return NO;
}else {
if (![player helpMode]) {
[player play];
}else{
NSLog(@"help mode");
}
}
return YES;
}
-(void)stopSound{
if ([self isPlaying]) {
[self stop];
}
}
@end
答案 0 :(得分:2)
我不确定这是否是导致错误的原因,但我想我会在这里的讨论中发布我的回复以使我的观点更清楚,因为我有更多的空间和代码格式。
不,你不必覆盖所有的方法,我只是要求确保我理解一切正确。
我要说的另一件就是像stopSound{}
一样,你应该使用自我而不是
SoundPlayer *player = [SoundPlayer sharedInstance];
所以将代码更改为此,运行它并查看其是否已修复,在下面发表评论以告知我结果。
-(BOOL)playSound:(NSURL*)url{
NSError *error;
// SoundPlayer *player = [SoundPlayer sharedInstance];
if([self isPlaying]){
[self stop];
}
//not sure if this should be self or super (i think super, try both)
//if you overrided the init then definitely self
//[self initWithContentsOfURL:url error:&error];
[super initWithContentsOfURL:url error:&error];
[self play];
if (self == nil){
NSLog(@"error %@ \n for file %@",[error description],[url path]);
return NO;
}else {
if (![self helpMode]) {
[self play];
}else{
NSLog(@"help mode");
}
}
return YES;
}
你真正做的就是创建一个指向self的指针,你创建一个玩家对象,因为它是一个单身人士。有了这个说我不知道为什么会让它崩溃,然后事实上你“应该”使用自我。
+ (SoundPlayer *)sharedInstance {
if (sharedInstance == nil) {
sharedInstance = [[super allocWithZone:NULL] init];
}
return sharedInstance;
}
请参阅here AVAudioPlayer只有2个init
方法,而且都不只是init
因此您没有完全初始化超类。您需要覆盖initWithContentsOfURL:url
方法并使用url参数初始化此对象及其super。只需确保将initWithContentsOfURL:url
放在.h和.m中。如果重要的话也请点击,但只是alloc
而不是allocWithZone
。