xib リソースを解放する必要がありますか?
-
09-06-2019 - |
質問
xib ファイルにリンクされた UILabel のようなものがある場合、ビューの割り当て解除時にそれを解放する必要がありますか?私が尋ねる理由は、割り当てていないため、解放する必要もないと思われるからですか?例 (ヘッダー内):
IBOutlet UILabel *lblExample;
実装では:
....
[lblExample setText:@"whatever"];
....
-(void)dealloc{
[lblExample release];//?????????
}
解決
現在ベストプラクティスと考えられていることに従えば、 すべき アウトレット プロパティは set アクセサーに保持しておく必要があるため、解放します。
@interface MyController : MySuperclass {
Control *uiElement;
}
@property (nonatomic, retain) IBOutlet Control *uiElement;
@end
@implementation MyController
@synthesize uiElement;
- (void)dealloc {
[uiElement release];
[super dealloc];
}
@end
このアプローチの利点は、メモリ管理のセマンティクスが明示的かつ明確になることです。 すべてのプラットフォームですべての nib ファイルに対して一貫して動作します。.
注記:次のコメントは、iOS 3.0 より前のバージョンにのみ適用されます。3.0 以降では、代わりに viewDidUnload のプロパティ値を単純に nil にする必要があります。
ただし、ここで考慮すべき点の 1 つは、コントローラーがユーザー インターフェイスを破棄し、オンデマンドで動的に再ロードする場合です (たとえば、nib ファイルからビューをロードするビュー コントローラーがある場合、要求に応じて -- たとえばメモリ不足が発生した場合) -- ビューが再び必要になった場合に再ロードできることを期待して、ビューを解放します)。この状況では、メイン ビューが破棄されるときに、他のアウトレットの所有権も放棄して、それらのアウトレットも割り当て解除できるようにする必要があります。UIViewController の場合、オーバーライドすることでこの問題に対処できます。 setView:
次のように:
- (void)setView:(UIView *)newView {
if (newView == nil) {
self.uiElement = nil;
}
[super setView:aView];
}
残念ながら、これによりさらに問題が発生します。UIViewController は現在その実装を行っているため、 dealloc
を使用した方法 setView:
アクセサー メソッド (単に変数を直接解放するのではなく)、 self.anOutlet = nil
呼ばれます dealloc
メモリ警告への応答としても...これはクラッシュにつながります dealloc
.
解決策は、アウトレット変数も必ず次のように設定することです。 nil
で dealloc
:
- (void)dealloc {
// release outlets and set variables to nil
[anOutlet release], anOutlet = nil;
[super dealloc];
}
他のヒント
Apple ドキュメントで探していたものを見つけました。つまり、オブジェクトを解放して保持するプロパティ (または単に @property や @synthesize) として設定できますが、UILabel などの場合はその必要はありません。
の
[anOutlet release], anOutlet = nil;
setView を記述した場合、この部分は完全に不要です。正しく。
Dealloc 時に解放しないと、メモリ使用量が増加します。
IB でラベルを作成すると、ある意味、ラベルが割り当てられます。
IB が行うことは、IBOutlet とそれらがどのように定義されているかを確認することです。IB が何らかのオブジェクトへの参照を割り当てるクラス変数がある場合、IB はそのオブジェクトに保持メッセージを送信します。
プロパティを使用している場合、IB は、値を明示的に保持するのではなく、値を設定するために必要なプロパティを利用します。したがって、通常は IBOutlet プロパティを保持としてマークします。
@property (nonatomic, retain) UILabel *lblExample;
したがって、どちらの場合でも (プロパティを使用するかどうかにかかわらず)、dealloc で release を呼び出す必要があります。
Nib のメイン ビューのサブビューである IBOutlet は、オブジェクトの作成時に自動解放メッセージが送信されるため、解放する必要はありません。Dealloc で解放する必要がある IBOutlet は、コントローラーや他の NSObject などのトップレベル オブジェクトだけです。これについてはすべて、上にリンクされている Apple ドキュメントで説明されています。
IBOutlet をプロパティとして設定せず、単にインスタンス変数として設定した場合でも、それを解放する必要があります。これは、initWithNib の際に、すべての IBOutlet にメモリが割り当てられるためです。したがって、これは、コード内でメモリを保持または割り当てていない場合でも、解放する必要がある特殊なケースの 1 つです。