[英]Obj-C iPhone: Memory Management
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時,仍然會出現內存問題。謝謝您的幫助。
在初始化音頻播放器后,將它們保留在另一個控制器(MVC)對象中。 然后只需通過從視圖控制器調用音頻控制器對象來重用現有的對象。
hotpaw2的答案是我建議做的。
但是您缺少的關鍵是內存管理。 您應該添加:
[theAudio play];
[theAudio release];
您在內存中分配的內容應該釋放。 因此,即使您每次都創建一個AVAudioPlayer。 您將釋放使用的內存。 這樣您就不會有任何泄漏。
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;
}
假設您要播放多個音頻文件,那么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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.