web-dev-qa-db-ja.com

-deallocではなく-(void)viewDidUnloadでオブジェクトを解放する必要があるのはいつですか?

-(void)viewDidUnloadは何に適していますか?

-deallocのすべてを解放することはできませんか?ビューがアンロードされた場合、-deallocはとにかく呼び出されませんか?

103
Thanks

すでに指摘されていることに加えて、-viewDidUnloadの背後にあるロジックについて詳しく説明したいと思いました。

それを実装する最も重要な理由の1つは、通常、UIViewControllerサブクラスにもビュー階層内のさまざまなサブビューへの所有参照が含まれていることです。これらのプロパティは、ペン先からロードするときにIBOutletsを介して、またはたとえば-loadView内でプログラム的に設定できます。

UIViewControllerによるサブビューの追加の所有権は、そのビューがビュー階層から削除され、サブビューもビューによって解放されるメモリを節約するために解放された場合でも、実際に割り当て解除されないことを意味しますUIViewController自体にも、それらのオブジェクトへの独自の未処理の保持参照が含まれています。これらのオブジェクトのUIViewController追加所有権を解放すると、それらのメモリも解放されます。

ここでリリースするオブジェクトは、通常、UIViewControllerビューがre-loadedである場合、Nibからまたは-loadViewの実装を介して再作成および再設定されます。

また、このメソッドが呼び出される時点では、UIViewControllerviewプロパティはnilであることに注意してください。

51
Sean Murphy

ドキュメントによると

View Controllerがビューとそのビューに関連付けられているオブジェクトを解放してメモリを解放する必要があるときに、メモリ不足の状態で呼び出されます。

同じ状況でdeallocnotと呼ばれます。この方法は、OS3以降でのみ使用できます。 iPhone OS 2.xで同じ状況に対処するのは本当に大変でした!

2015年7月更新:iOS 6ではviewDidUnloadが非推奨になったことに注意する必要があります。「メモリ不足の状態ではビューがパージされなくなり、このメソッドは呼び出されないためです。」そのため、現代のアドバイスは、それを心配してdeallocを使用しないことです。

21

これは、通常_@property_を"(nonatomic, retain)"として設定し、そのために作成されたセッターが現在のオブジェクトを解放してから引数を保持するためです。

_self.property = nil;
_

...のラインに沿って何かをします:

_[property release];
property = [nil retain];
_

したがって、メモリ管理(既存のオブジェクトの解放)とポインターのnilへの割り当て(nilポインターにメッセージを送信するとnilが返されるため)を1石で2羽の鳥を殺しています。

お役に立てば幸いです。

9
gazzaaa87

viewDidUnloadは、ビューではなく、View Controllerのメソッドであることに注意してください。 view'sdeallocメソッドは、ビューがアンロードされると呼び出されますが、view controller'sdeallocメソッドは後まで呼び出されない場合があります。

メモリ不足の警告が表示され、ビューが表示されない場合、たとえばUIImagePickerControllerを使用してユーザーに写真を撮らせた場合などに、ビューがアンロードされます。その後、ビューを再ロードする必要があります。

8
David Maymudes

AppleはviewWillUnloadを非推奨にしたので、didReceiveMemoryWarningまたはdeallocを使用してオブジェクトを解放する必要があります。

IOS 6では、UIViewControllerのviewWillUnloadおよびviewDidUnloadメソッドは廃止されました。これらのメソッドを使用してデータを解放する場合は、代わりにdidReceiveMemoryWarningメソッドを使用します。また、このメソッドを使用して、View Controllerのビューへの参照が使用されていない場合は解放することもできます。これを行う前に、ビューがウィンドウ内にないことをテストする必要があります。

結論:

View Controllerにはビュープロパティがあります。通常、ペン先またはコードの一部は、このビューに他のビューを追加します。これは、次のように-viewDidLoadメソッド内で頻繁に発生します。

- (void)viewDidLoad {
    [super viewDidLoad];
    [self createManyViewsAndAddThemToSelfDotView];
}

さらに、nibファイルはボタンを作成し、それをView Controllerのビューに追加する場合があります。

IPhone OS 2.2では、システムから-didReceiveMemoryWarningが呼び出されたときに、何かを解放してメモリを解放する必要がありました。理にかなっている場合は、View Controllerのビュー全体を解放できます。または、その中にある大きなメモリ消費コンテンツ。

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}

現在、新しいOS 3.0には、-viewDidUnloadメソッドがあります。これは、メモリ不足のためにビューがアンロードされたときにシステムから呼び出されます(修正してください:正確にいつ呼び出されますか?)

-viewDidUnloadは、View Controller自体とビューの両方が所有していたすべてのオブジェクトを解放するために使用されます。理由:ビューコントローラーがビューの子、つまりボタンへの参照を保持している場合、保持カウントが1以上であるため、参照された子ビューは解放されません。-viewDidUnloadで解放された後、解放できますメモリから。

6
Thanks

View ControllerがNavigation Controllerスタックからポップされ、他の場所に保持されていない場合、割り当てが解除され、viewDidUnloadの代わりにdeallocが呼び出されます。 loadViewで作成されたビューをdeallocで解放する必要がありますが、deallocが呼び出されるとすぐに変数が存在しなくなるため、変数をnilに設定する必要はありません。

5
Colin

たとえば、loadViewメソッドで保持したUIImageView、またはより良いのはそのUIImageViewにあった画像など、保持しているサブビューを解放できます。

3
drvdijk