iPhone初学者在这里,我正在创建一个名为Piano Master的简单音乐iPhone应用程序,当点击一个按钮时会产生声音。
这是我的代码:
MusicViewController.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import "PianoMasterAppDelegate.h"
@interface MusicViewController : UIViewController
<AVAudioPlayerDelegate> {}
- (IBAction)buttonClick:(id)sender;
@end
MusicViewController.m
#import "MusicViewController.h"
@implementation MusicViewController
- (IBAction)buttonClick:(id)sender
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"Piano1" ofType:@"wav"];
AVAudioPlayer *theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path error:NULL];
theAudio.delegate = self;
[theAudio play];
}
单击按钮时会播放声音,但每次单击该按钮时,都会创建一个新的AVAudioPlayer,有关如何有效管理此内存问题的最佳方法是什么?我曾想过为MusicViewController创建一个AVAudioPlayer实例并使用它,但如果我每次都继续分配一个新的AVAudioPlayer,那么仍然会有内存问题...... 任何帮助都很有用,谢谢。
答案 0 :(得分:1)
初始化后,将音频播放器保留在其他控制器(MVC)对象中。然后通过从视图控制器调用音频控制器对象来重用现有的。
答案 1 :(得分:0)
hotpaw2的回答是我建议做的。
但是你缺少的一个关键是内存管理。你应该添加:
[theAudio play];
[theAudio release];
你在内存中分配的内容应该释放。所以即使你每次都在创建一个AVAudioPlayer。你将释放使用的内存。所以你不会有任何泄漏。
答案 2 :(得分:0)
MusicViewController.h文件
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import "PianoMasterAppDelegate.h"
@interface MusicViewController : UIViewController <AVAudioPlayerDelegate> {
AVAudioPlayer* _theAudio;
}
- (IBAction)buttonClick: (id)sender;
@end
MusicViewController.m文件
#import "MusicViewController.h"
@implementation MusicViewController
- (void)dealloc {
[_theAudio release];
[super dealloc];
}
- (AVAudioPlayer*)theAudio {
if (_theAudio == nil) {
NSString* path = [[NSBundle mainBundle] pathForResource: @"Piano1" ofType: @"wav"];
_theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL: [NSURL fileURLWithPath: path error: nil];
[_theAudio setDelegate: self];
}
return _theAudio;
}
- (IBAction)buttonClick: (id)sender {
[self.theAudio play];
}
您可能还想在viewDidUnload方法中释放theAudio以释放内存,请确保将指针设置为nil afterword,如下所示:
- (void)viewDidUnload {
[_theAudio release];
_theAudio = nil;
}
答案 3 :(得分:0)
假设您想要播放多个不同的音频文件,AVAudioPlayers的字典可以正常工作。例如,第一次请求声音文件时,创建AVAudioPlayer对象并将其放入声音字典中,然后对于每个后续请求,只需从字典中抓取现有的AVAudioPlayer对象。
这是一个简单的实现:
@interface MusicViewController : UIViewController <AVAudioPlayerDelegate> {
NSMutableDictionary *sounds;
}
- (IBAction)buttonClick:(id)sender;
- (AVAudioPlayer *)playerForSoundFile:(NSString *)fileName;
@end
@implementation MusicViewController
- (id)init
{
if (! (self = [super init]))
return nil;
sounds = [[NSMutableDictionary alloc] init];
return self;
}
- (void)dealloc
{
[sounds release];
[super dealloc];
}
- (AVAudioPlayer *)playerForSoundFile:(NSString *)fileName
{
AVAudioPlayer *player = [sounds objectForKey:fileName];
if (! player) {
NSString *path = [[NSBundle mainBundle] pathForResource:fileName
ofType:@"wav"];
NSURL *url = [NSURL fileURLWithPath:path];
player = [[[AVAudioPlayer alloc] initWithContentsOfURL:url] autorelease];
player.delegate = self;
[sounds setObject:player forKey:fileName];
}
return player;
}
- (IBAction)buttonClick:(id)sender
{
AVAudioPlayer *theAudio = [self playerForSoundFile:@"Piano1"];
[theAudio play];
}
@end
请注意,AVAudioPlayer是“自动释放”,然后添加到“声音”字典中。这意味着当字典被销毁时,所有AVAudioPlayers也将如此。如果不清楚,您应该阅读Objective-C中的内存管理:http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/MemoryMgmt/MemoryMgmt.html