我的iOS
应用程序^^需要帮助。我想知道我是否正确发布AVAudioPlayer
。
MyViewController.h
#import <UIKit/UIKit.h>
@interface MyViewController : UIViewController
{
NSString *Path;
}
- (IBAction)Playsound;
@end
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
答案 0 :(得分:3)
我认为您实施解决方案的方式可能更好,并了解为什么会帮助您学习。
首先,在Objective-C(至少是Cocoa和Cocoa Touch)中使用以小写字母开头的变量和方法名称。例如,您的“媒体”变量应为“媒体”,而“PlaySound”方法应为“playSound”。
其次,您的“media”变量被声明为全局变量,最好将其声明为MyViewController.h文件中@interface
中的实例变量。因此,MyViewController
的每个实例都有一个名为“media”的实例变量,它更适合面向对象的封装概念。就个人而言,我会把变量称为“玩家”,因为我觉得这个变量更好(我从这里开始使用“玩家”)。
第三,如果你的“playSound”总是发出与你相同的声音,那么最好将“media”对象的分配移动到“init ...”方法(例如,initWithNibName) :bundle:方法)。这样你只需要实例化一次对象而不是每次调用你的“playSound”方法(我认为它可以被多次调用)。你是“playSound”方法只需要调用[player play]
。这样就没有理由将你的路径作为实例变量。
最后,如果您按上述方式执行操作,则在dealloc方法中调用[player release]是有意义的。当释放类的实例并释放属于它的“播放器”实例时,将调用dealloc方法。
以下是我的更改内容。
<强> MyViewController.h 强>
#import <UIKit/UIKit.h>
@class AVAudioPlayer;
@interface MyViewController : UIViewController
{
AVAudioPlayer *player;
}
- (IBAction)playSound;
@end
<强> MyViewController.m 强>
#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
答案 1 :(得分:0)
在Cocoa中思考记忆的最好方法是,“我有没有发布我拥有的东西?”。在您给出的示例中,您通过分配其内存来创建“Media”变量的所有权,因此在您的类和该分配之间创建一个合同,以便在您完成对象时释放您对该对象的所有权。
换句话说,当你创建那个对象时,它的保留计数为1,这意味着你是它的拥有者,并且一旦完成它就需要放弃它的所有权。这可能不一定意味着该对象将立即解除分配; Cocoa内存范例意味着如果你收到一个你没有创建的对象,但需要它“保持活力”足够的时间让你使用它,你可以调用'retain',然后'release'当你是完成它。
在上面的附录中,是'autorelease'的概念; pathForResource:
方法在返回时将对象的所有权传递给你 - 换句话说,在创建对象之后,它通过在返回对象之前调用'autorelease'来放弃所有权本身,因此强迫你的类负责决定如何处理它(你可以'保留'它,然后在某个地方稍后要求'释放',或者只是在它被解除分配之前使用它。)
我建议阅读Apple的内存指南;一旦你掌握了你将要设定的概念: Memory Management Programming Guide