Iphone 如何正确释放音频?[AVAudioPlayer]

Iphone 如何正确释放音频?[AVAudioPlayer],iphone,objective-c,memory-management,avaudioplayer,Iphone,Objective C,Memory Management,Avaudioplayer,我需要有关我的iOSapplication^^的帮助,。我想知道我是否正确发布了AVAudioPlayer MyViewController.h #import <UIKit/UIKit.h> @interface MyViewController : UIViewController { NSString *Path; } - (IBAction)Playsound; @end #import <UIKit/UIKit.h> @class AVA

我需要有关我的
iOS
application^^的帮助,。我想知道我是否正确发布了
AVAudioPlayer

MyViewController.h

#import <UIKit/UIKit.h>

@interface MyViewController : UIViewController
{
    NSString    *Path;
}

- (IBAction)Playsound;

@end
#import <UIKit/UIKit.h>

@class AVAudioPlayer;

@interface MyViewController : UIViewController
{
    AVAudioPlayer *player;
}

- (IBAction)playSound;

@end
#导入
@接口MyViewController:UIViewController
{
NSString*路径;
}
-(i)播放声音;
@结束
MyViewController.m

#import <AVFoundation/AVAudioPlayer.h>
#import "MyViewController.h"

@implementation MyViewController

AVAudioPlayer *Media;

- (IBAction)Playsound
{
   Path = [[NSBundle mainBundle] pathForResource:@"Sound" ofType:@"wav"];
   Media = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:Path] error:NULL];
   [Media play];
}

- (void)dealloc
{
   [Media release];
   [super viewDidUnload];
}

@end
#import <AVFoundation/AVAudioPlayer.h>
#import "MyViewController.h"

@implementation MyViewController

- (id)initWithNibName:(NSString*)nibName bundle:(NSBundle*)nibBundleOrNil
{
    if (self = [super initWithNibName:nibName bundle:nibBundleOrNil]) {
        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Sound" ofType:@"wav"];
        player = [AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath] error:NULL];
    }
    return self;
}

- (IBAction)playSound
{
   [player play];
}

- (void)dealloc
{
   [player release];
   [super dealloc];
}

@end
#导入
#导入“MyViewController.h”
@MyViewController的实现
AVAudioPlayer*媒体;
-(i)播放声音
{
Path=[[NSBundle mainBundle]pathForResource:@“Sound”类型:@“wav”];
Media=[[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:Path]错误:NULL];
[媒体播放];
}
-(无效)解除锁定
{
[媒体发布];
[超级视频下载];
}
@结束

思考Cocoa中内存的最佳方式是,‘我发布了我拥有的任何东西吗?’。在您给出的示例中,您通过分配“Media”变量的内存来创建该变量的所有权,从而在您的类和该分配之间创建一个契约,以便在处理完对象后释放您对该对象的所有权

换句话说,当您创建该对象时,它的保留计数为1,这意味着您是该对象的所有者,并且需要在使用完该对象后放弃该对象的所有权。这不一定意味着该对象将立即被解除分配;Cocoa内存范例意味着,如果您曾经收到一个您没有创建的对象,但需要它“保持活动”足够的时间来处理它,您可以调用“保留”,然后在处理完它后再调用“释放”

在上述附录中,是“自动释放”的概念;
pathForResource:
方法在对象返回时将对象的所有权传递给您——换句话说,在创建对象之后,它通过在返回对象之前调用对象上的“autorelease”来放弃所有权,因此强制您的类负责决定如何处理它(你可以“保留”它,然后在以后的某个地方要求“发布”,或者干脆使用它直到它被释放)

我建议你阅读苹果的《内存指南》;一旦你掌握了这些概念,你就会:

我认为您实施解决方案的方式可能会更好,了解原因将有助于您学习

首先,Objective-C(至少是Cocoa和Cocoa Touch)中的惯例是以小写字母开头命名变量和方法名称。例如,“媒体”变量应该是“媒体”,而“播放声音”方法应该是“播放声音”

其次,您的“media”变量被声明为全局变量,最好在MyViewController.h文件的
@interface
中将其声明为实例变量。因此,
MyViewController
的每个实例都有一个名为“media”的实例变量哪一个更符合面向对象的封装概念。就我个人而言,我会将变量称为“player”,因为在我看来,它更适合描述变量(从现在开始我将使用“player”)

第三,如果您的“播放声音”总是播放与您拥有的声音相同的声音,那么最好将“媒体”对象的分配移动到“init…”方法(例如initWithNibName:bundle:method)。这样,您只需实例化一次对象,而不是每次调用“播放声音”方法(我假设它可以被多次调用)。您的“播放声音”方法只需要调用
[player play]
。这样就没有理由将您的路径作为实例变量

最后,如果您执行上述操作,那么在dealloc方法中调用[player release]是有意义的。当类的一个实例被解除分配并且该实例被解除分配属于它的“player”实例时,将调用dealloc方法

下面是我所做的更改

MyViewController.h

#import <UIKit/UIKit.h>

@interface MyViewController : UIViewController
{
    NSString    *Path;
}

- (IBAction)Playsound;

@end
#import <UIKit/UIKit.h>

@class AVAudioPlayer;

@interface MyViewController : UIViewController
{
    AVAudioPlayer *player;
}

- (IBAction)playSound;

@end
#导入
@类音频层;
@接口MyViewController:UIViewController
{
AVAudioPlayer*播放器;
}
-(i)播放声音;
@结束
MyViewController.m

#import <AVFoundation/AVAudioPlayer.h>
#import "MyViewController.h"

@implementation MyViewController

AVAudioPlayer *Media;

- (IBAction)Playsound
{
   Path = [[NSBundle mainBundle] pathForResource:@"Sound" ofType:@"wav"];
   Media = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:Path] error:NULL];
   [Media play];
}

- (void)dealloc
{
   [Media release];
   [super viewDidUnload];
}

@end
#import <AVFoundation/AVAudioPlayer.h>
#import "MyViewController.h"

@implementation MyViewController

- (id)initWithNibName:(NSString*)nibName bundle:(NSBundle*)nibBundleOrNil
{
    if (self = [super initWithNibName:nibName bundle:nibBundleOrNil]) {
        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Sound" ofType:@"wav"];
        player = [AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath] error:NULL];
    }
    return self;
}

- (IBAction)playSound
{
   [player play];
}

- (void)dealloc
{
   [player release];
   [super dealloc];
}

@end
#导入
#导入“MyViewController.h”
@MyViewController的实现
-(id)initWithNibName:(NSString*)nibName bundle:(NSBundle*)nibBundleOrNil
{
if(self=[super initWithNibName:nibName bundle:nibBundleOrNil]){
NSString*文件路径=[[NSBundle mainBundle]路径用于资源:@“Sound”类型:@“wav”];
player=[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:filePath]错误:NULL];
}
回归自我;
}
-(i)播放声音
{
[玩家游戏];
}
-(无效)解除锁定
{
[玩家释放];
[super dealoc];
}
@结束

在dealloc方法中,您应该调用[super dealloc],而不是[super viewDidUnload]。我以前没有注意到这一点,所以我编辑了我的帖子。