2011-01-09 116 views
1

我需要幫助我的iOS應用程序^^ ,.我想知道我是否正確釋放AVAudioPlayer如何正確釋放音頻? [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 

回答

3

我認爲你實施解決方案的方式可能會更好,理解爲什麼會幫助你學習。

首先,在Objective-C(至少Cocoa和Cocoa Touch)中約定變量和方法名稱以小寫字母開頭。例如,你的「Media」變量應該是「media」,你的「PlaySound」方法應該是「playSound」。其次,你的「媒體」變量被聲明爲一個全局變量,最好在你的MyViewController.h文件中的@interface中聲明它爲一個實例變量。因此,每個MyViewController實例都會有一個名爲「media」的實例變量,它更適合面向對象的封裝概念。就個人而言,我會稱之爲變量「player」,因爲在我看來,這個變量描述的是更好的變量(我將從這裏開始使用「player」)。第三,如果你的「playSound」總是會播放相同的聲音,那麼將「媒體」對象的分配移動到「init ...」方法可能會更好(例如, initWithNibName:bundle:method)。這樣你只實例化對象一次,而不是每次調用「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 
+0

在dealloc方法,你應該調用[超級的dealloc]而不是[超級viewDidUnload。之前我沒有注意到,所以我編輯了我的帖子。 – yabada 2011-01-10 00:14:22

0

想到的內存可可是最好的方式, '我有什麼釋放我自己?'。在你給出的例子中,你通過分配它的內存來創建'Media'變量的所有權,因此在你的類和這個分配之間創建了一個契約,當你完成它時釋放你對象的所有權。

換句話說,當你創建這個對象時,它的保留計數爲1,這意味着你是它的所有者,並且一旦完成它就需要放棄它的所有權。這可能不一定意味着該對象會立即釋放; Cocoa記憶範式意味着如果你收到一個你沒有創建的對象,但是需要它保持足夠的時間讓你使用它,你可以稱之爲'保留',然後'釋放'完成了它。

在上述附錄中,是'autorelease'的概念;在返回對象時,方法會將對象的所有權傳遞給您 - 換言之,在創建對象後,它會在返回對象之前通過調用對象的「autorelease」放棄所有權本身,因此迫使您的課程負責決定要執行的操作(你可以'保留'它,然後在某個地方需要'釋放',或者直接使用它,直到它被釋放)。

我推薦閱讀蘋果的內存指南;一旦你已經掌握了你將要設置的概念: Memory Management Programming Guide