2011-01-09 3 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"にする必要があります。

第2に、 "media"変数がグローバル変数として宣言されており、MyViewController.hファイルの@interfaceにインスタンス変数として宣言する方がよいでしょう。したがって、MyViewControllerの各インスタンスには、オブジェクト指向のカプセル化の概念に適した "media"というインスタンス変数があります。個人的には変数が "player"と呼ばれるのは、変数が何が良いかを記述するように思えるからです(私はここから "player"を使用します)。

第3に、あなたの "playSound"が常にあなたと同じ音を再生しようとしている場合、 "メディア"オブジェクトの割り当てを "init ..." initWithNibName:bundle:メソッド)。この方法で、オブジェクトを一度しかインスタンス化せず、 "playSound"メソッドが呼び出されるたびに呼び出されるわけではありません(私は複数回呼び出すことができます)。あなたは "playSound"メソッドは[player play]を呼び出すだけです。このようにして、パスをインスタンス変数として持つ理由はありません。

最後に、上記のようにすれば、deallocメソッドで[player release]を呼び出すことは意味があります。deallocメソッドは、クラスのインスタンスの割り当てが解除され、そのクラスに属する「player」のインスタンスの割り当てが解除されたときに呼び出されます。

私の変更点は次のとおりです。 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

あなたは[スーパーviewDidUnload] [スーパーのdealloc]を呼び出し、いないする必要があります。私はこれを気付かずに私の投稿を編集しました。 – yabada

0

ココアのメモリを考えるための最良の方法ですが、 '私は私が所有して何かをリリースしてきました?'。あなたが与えた例では、メモリを割り当てることによって 'Media'変数の所有権を作成します。そのため、クラスとその割り当ての間に契約を結んで、オブジェクトの所有権を解放します。

つまり、そのオブジェクトを作成したとき、オブジェクトの所有者であることを意味し、オブジェクトの所有権を放棄する必要があります。これは必ずしもオブジェクトがすぐに割り当て解除されることを意味するわけではありません。ココアの記憶パラダイムは、あなたが作成していないオブジェクトを受け取った場合でも、それを使って作業するのに十分な時間を「生きている」必要がある場合は、「保持」と呼んでから、それで終わった。

上記の補遺では、「自動解放」の概念です。 pathForResource:メソッドは、返されたときにオブジェクトの所有権を渡します。つまり、オブジェクトを作成した後、オブジェクトを返す前にオブジェクトに対して 'autorelease'を呼び出すことによって所有権を放棄します。したがって、クラスに何をすべきかを決める責任があります(あなたはそれを「保持」することができ、後でどこかの「リリース」を要求するか、単に解放されるまでそれを使用することができます)。

Appleのガイドをメモリに読み込むことをお勧めします。コンセプトを習得すれば、設定されます: Memory Management Programming Guide

関連する問題