我有一个类,我调用它来利用 AVAudioPlayer
,并且在播放音频时一切正常,但是当 -audioPlayerDidFinishPlaying:
被称为我的NSLog()
命令表示玩家被释放;问题是应用程序稍后就会崩溃。我应该提到 audioPlayer
是此类中的一个 ivar。这是代码:
-(id) initWithFileName:(NSString *)sndFileName
{
[super init];
sndFileToPlay = [[NSString alloc] initWithString:sndFileName];
return self;
}
-(void)dealloc {
[audioPlayer release];
self.audioPlayer.delegate = nil;
self.audioPlayer = nil;
[super dealloc];
}
-(void)play
{
[self playSound:sndFileToPlay];
}
-(void)playSound:(NSString *)fileName
{
NSString *fname, *ext;
NSRange range = [fileName rangeOfString:@"."];
int location = range.location;
if( location > 0 )
{
fname = [fileName substringWithRange:NSMakeRange(0, location)];
ext = [fileName substringFromIndex:location+1];
[self playSound:fname :ext];
}
}
—
-(void)playSound:(NSString *)fileName :(NSString *)fileExt
{
NSBundle *mainBundle = [NSBundle mainBundle];
NSURL *fileURL = [NSURL fileURLWithPath:
[mainBundle pathForResource:fileName ofType:fileExt] isDirectory:NO];
if (fileURL != nil)
{
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: fileURL
error: nil];
[fileURL release];
[audioPlayer setDelegate:self];
[audioPlayer play];
}
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player
successfully:(BOOL)flag
{
NSLog(@"Releasing");
[audioPlayer release];
}
最佳答案
您的代码存在一些问题。
例如,在您的 dealloc
中:
[audioPlayer release];
self.audioPlayer.delegate = nil;
self.audioPlayer = nil;
您正在释放audioPlayer,然后,在已释放(可能是已释放)的播放器上,您将委托(delegate)设置为nil,然后将属性设置为nil,这将再次释放它。删除[audioPlayer release];
。
在您的 audioPlayerDidFinishPlaying:successively:
中,您也释放了播放器,但尚未将变量设置为 nil
。这可能会导致崩溃,因为当您再次访问该变量时,该内存地址可能有不同的对象。请使用该属性,并像在 dealloc
中那样执行操作:
self.audioPlayer.delegate = nil;
self.audioPlayer = nil;
然后,在 playSound::
(呃,未命名的第二个参数!)中,您过度释放了 fileURL
。 -[NSURL fileURLWithPath:isDirectory:]
返回一个自动释放的对象,您不能释放它。
最后但也许并非最不重要的一点是,您泄漏了 sndFileToPlay
,您需要在 dealloc
方法中释放它。而不是 sndFileToPlay = [[NSString alloc] initWithString:sndFileName];
只需执行 sndFileToPlay = [sndFileName copy];
。
您可能想阅读有关 Objective-C 内存管理的内容。一旦您了解了三四个经验法则,这就不难了。
关于iphone - audioPlayerDidFinishPlaying : called之后的EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6426133/