2011-03-02 131 views
0

iPhone初學者在這裏,我正在創建一個名爲Piano Master的簡單音樂iPhone應用程序,當單擊按鈕時會產生聲音。Obj-C 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,那麼仍然會出現內存問題... 任何幫助都很有用,謝謝。

回答

1

將音頻播放器保存在另一個控制器(MVC)對象的某個位置,並初始化它們。然後通過調用視圖控制器中的音頻控制器對象來重用現有的。

0

hotpaw2的答案是我建議做的。

但你缺少的關鍵是內存管理。您應該添加:

[theAudio play]; 
[theAudio release]; 

您在內存中分配的內容您應該釋放。所以即使你每次都創建一個AVAudioPlayer。你將釋放使用的內存。所以你不會有任何泄漏。

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]; 
} 

您可能還需要釋放theAudio在viewDidUnload方法以釋放內存,請確保您的指針設置爲nil後記是這樣的:

- (void)viewDidUnload { 
    [_theAudio release]; 
    _theAudio = nil; 
} 
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

+0

當我按下按鈕時沒有聲音播放...... – user544359 2011-03-06 00:39:28