2010-01-23 62 views
0

内存泄漏在试图修复内存泄漏,我想在我的.m文件来实现此代码:试图修复使用AVAudioPlayer

AVAudioPlayer *audioPlayer; 

- (AVAudioPlayer *)audioPlayerWithContentsOfFile:(NSString *) path { 
    NSData *audioData = [NSData dataWithContentsOfFile:path]; 
    AVAudioPlayer *player = [AVAudioPlayer alloc]; 
    if([player initWithData:audioData error:NULL]) { 
     [player autorelease]; 
    } else { 
     [player release]; 
     player = nil; 
    } 
    return player; 
} 

然后试图通过叫它:

[audioPlayer audioPlayerWithContentsOfFile: [NSString stringWithFormat:@"%@/knock_knock.wav", [[NSBundle mainBundle] resourcePath]]]; 

头文件具有: AVAudioPlayer不得响应:

- (AVAudioPlayer *) audioPlayerWithContentsOfFile: (NSString *) path; 

与一个警告编译到'-audioPlayerWithContentsOfFile:' (没有匹配签名的消息将被认为返回'id'并接受'...'作为参数。

每当我遇到这种语言时,我会遇到这样的事情,我花了数小时试图弄清楚。任何人都可以帮忙?一如既往,先谢谢你。

地理...

回答

0
  • 不构成这样的路径。使用NSBundle的pathForResource:ofType:或类似的。

  • 请勿将+alloc-init(或任何其他指定的初始化程序)中分割出来。这是一个风格问题,标准是[[AVAudioPlayer alloc] initWithData: foo error: &bar]

  • 处理错误并在出现问题时将其打印出来。它通常会提供线索。

现在,你的实际错误。

AVAudioPlayer may not response to '-audioPlayerWithContentsOfFile:'

这表明你正在尝试的方法调用发送到AVAudioPlayer类的一个实例。这是打算吗?即是你的.m文件执行类AVAudioPlayer

你的代码看起来有点时髦。你有一个名为audioPlayer的实例变量,但是我没有看到任何分配给它的东西。

此外,请确保包含方法声明的头文件被导入到.m中。并确保你正在传递一个实例,而不是类。

3

首先,尽量避免类似这样的语句:

AVAudioPlayer *player = [AVAudioPlayer alloc]; 

,因为你留下了一个未初始化的对象,你可能会发生,只是事后忘了初始化它。在正常情况下,您应该将始终 send -init ...方法分配给新分配的对象。换句话说,正确的方法是在一个“句子”中调用+ alloc和-init。其次,如果AVAudioPlayer的-initWithData:error:返回nil,你不能释放它,因为你发送-autorelease消息到nil。按照惯例,如果一个对象不能被引用,它应该释放它自己并返回nil。这是AVAudioPlayer无法读取或识别音频数据的功能。换句话说,不要试图自己释放它。

因此,你的方法的简化版本是这样的:

- (AVAudioPlayer *)audioPlayerWithContentsOfFile:(NSString *) path { 
    NSData *audioData = [NSData dataWithContentsOfFile: path]; 
    return [[[AVAudioPlayer alloc] initWithData:audioData error: NULL] autorelease]; 
} 

请务必将邮件发送给正确的类,因为AVAudioPlayer没有实现你的-audioPlayerWithContentsOfFile:方法。看看它的定义和实施。

@interface SomeClass : NSObject 
... 
- (AVAudioPlayer *)audioPlayerWithContentsOfFile:(NSString *) path; 
@end 

以上定义-audioPlayerWithContentsOfFile:类SomeClass的实例,所以你应该将消息发送到SomeClass的,不AVAudioPlayer的实例。如果您想定义AVAudioPlayer类这种方法,而是执行此操作:

@interface AVAudioPlayer (MyExtensions) 
+ (AVAudioPlayer *)audioPlayerWithContentsOfFile:(NSString *) path; 
@end 

@implementation AVAudioPlayer (MyExtensions) 
+ (AVAudioPlayer *)audioPlayerWithContentsOfFile:(NSString *) path { 
     NSData *audioData = [NSData dataWithContentsOfFile: path]; 
     return [[[AVAudioPlayer alloc] initWithData:audioData error: NULL] autorelease]; 
} 
@end 

要使用它:

[AVAudioPlayer audioPlayerWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"knock_knock" ofType:@"wav"]]; 
+0

关于你的答案的第一部分:乔治没有张贴的由来代码,因此你缺乏上下文。看到这里:http://blog.zincroe.com/2009/06/avaudioplayer-memory-leak/否则,+1。 – 2011-05-23 13:20:28