2011-06-22 6 views
2

、あなたがInterface Builderで設定された任意の出口は をリリースし、viewDidUnloadにnilに設定され、またのdeallocに解放する必要がありますする必要があります。プログラムが作成したサブビューとviewDidUnload

は(参照:When should I release objects in viewDidUnload rather than in dealloc?)を実装するための最も重要な理由の

ワン[viewDidUnload]のUIViewControllerのサブクラスは、一般的にも、ビュー階層内のさまざまなサブビューへの参照を所有している含まれていることです。これらのプロパティは、ペン先からロードするときにIBOutletsを介して設定するか、またはプログラム内で[emphasis added]のようにプログラムで設定することができます。

私の質問です、私たちは本当に(Interface Builderをせずに)loadViewメソッドでプログラム作成されたビュー階層でサブビューのためviewDidUnloadを実装する必要がありますか?

答えて

5

どのように作成したか、別の場所で参照する必要があるかどうかによって異なります。例えば

:someButtonはloadViewメソッド内自動解放されるので、あなたがviewDidUnloadを実装する必要はありません上記の場合

- (void)loadView 
{ 
    [super loadView]; 

    UIButton *someButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    someButton.frame = CGRectMake(0, 0, 50, 50); 
    [self.view addSubview: someButton]; 
} 

もう一つの例:あなたはあなたの周りぶら下がっsomeButtonへの別の参照を持っているように、viewDidUnloadを使いたいでしょう。この例では

- (void)loadView 
{ 
    [super loadView]; 

    self.someButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    someButton.frame = CGRectMake(0, 0, 50, 50); 
    [self.view addSubview: someButton]; 
} 

。 viewDidUnloadでそのボタンを解放し、リファレンスをリセットして、不適切に使用したりメモリを解放したりしないようにします。この場合、viewDidUnloadが呼び出されない場合に備えて、deallocメソッドのボタンも解放したいと思うでしょう。

+0

は完全に正しいです!あなたのビューコントローラは、メモリをリークしたりゾンビにアクセスしたりすることなく、多くのloadView(+ viewDidLoad)/ viewDidUnload-Cyclesを通過できるはずです。最良の例は、Tab Bar ControllerのVCです。タブをクリックするとloadView/viewDidUnloadを経由して割り当てられます。 –

+0

カスタムloadViewメソッドで[super loadView]を呼び出さないでください。コードは次のようになります:self.view = [[[UIView alloc] initWithFrame:[UIScreen mainScreen] .applicationFrame] autorelease]; –

+0

なぜWubaoを説明したいですか? [super loadView]を呼び出す際に問題が発生したことはありません。 – hundreth

0

あなたのdealloc方法でそれを行います。 viewDidUnloadが呼び出される保証はありません。これは通常、コントローラがビューをアンロードする必要がある場合にのみ呼び出されます。メモリ警告があるとき。一方、常にinit/deallocのペアリングが呼び出されます。

+0

私は** dealloc **で私のサブビューを公開しています。私も*私のサブビューを解放し、** viewDidUnload **でそれらをnilに設定する必要がありますか? –

+0

@Seth Lowenstein:それは異なります。ドキュメントから:「後で簡単に再作成できるオブジェクトの場合のみ、viewDidLoadメソッドまたはアプリケーションの他の部分からオブジェクトを削除する必要があります。このメソッドを使用して、ユーザーデータなどの情報を簡単に解放できないようにしてください再現された " – csano

2

あなたは確かにです。です。しかし、Appleのサンプルを見ると、deallocだけを使用することがあることがわかります。あなたのオブジェクトが使用後にある程度合理的な時間に割り当て解除されることを知っているなら、これは完全に合理的だと私は思う。しかし、特定の例外的なケースではviewDidUnloadが呼び出されないかもしれないので、私はこのパターンに従います。あなたも、その問題を単純化するために、あなたのクラスは、サブクラスアプリケーション固有のView Controllerオブジェクトからこれを行うことが

-(void)releaseRetainedXibAndViewDidLoadObjects 
{ 
    self.myLabel = nil; 
    self.myImage = nil; 
} 

-(void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    [self releaseRetainedXibAndViewDidLoadObjects]; 
} 

-(void)dealloc 
{ 
    self.myObject = nil; 
    [self releaseRetainedXibAndViewDidLoadObjects]; 
    [super dealloc]; 
} 

:私は実際に解放方法このような長い名前を呼び出すことはありません。

+0

** viewDidUnload **と* dealloc **で同じ "リリースメソッド"を呼び出すことは賢明ですか?通常、私は@propertyを "(非原子的な、保持する)"に設定します。そのため、あなたのために作成されたセッターは現在のオブジェクトを解放し、引き続きその引数を保持します。つまり、** viewDidUnload **の 'self.myProperty = nil;'は '[myProperty release]のようなことをします; myProperty = [nil retain]; '...次に、** dealloc **では、私たちが行うのは' [myProperty release] 'です。 –

+0

私のパターンは完全に安全で、viewDidUnloadとは違ってdeallocでそれを行う必要はありません。保持されているプロパティーの場合、self.property = nilは[property release]、property = nilと等価です。 deallocでは、これを無条件に設定することは重要ではありませんが、誤って後でアクセスしようとする場合には、まだ良い考えです。冗長性と同じ機能を定義する必要がある場所の数を減らす必要があります。 –

関連する問題