簡體   English   中英

Obj-C iPhone:內存管理

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM