7

私のプロジェクトでは、Interface Builderを使用していませんが、説明の仕方がわからないことに気づきました。まだ。だから、要点まで。IBを使用していて、コントローラーでUILabelやUIButtonなどのユーザーインターフェイスの要素を定義している場合は、この醜いプレフィックスIBOutletと「weak」修飾子を使用します。これは音楽のように機能します。しかし、IBを使用せず、コードからユーザーインターフェイス全体を定義することにした場合、それは機能しません。

UILabelをコントローラーに追加したいとします(IBを使用)。私はこのi*.hファイルのようなものを持っています:

@property (nonatomic, weak) IBOutlet UILabel * label;

そして、*。mファイルでこれ以上何もする必要はありません。しかし、*。xibファイルを削除して、たとえば次のようなinitメソッドの1つでUILabelを設定しようとすると、次のようになります。

self.label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,100,20)];
self.label.text = @"some text";
[self.view addSubview:self.label];

*.hファイルを次のように変更するまで機能しません。

@property (nonatomic, strong) UILabel * label;

これで、weakとstrongの違いはわかりましたが、IBを使用するときにUI要素にweakを使用できる理由がわかりません。何かがこれらの要素への強力なポインタを維持する必要がありますよね?でもなに?2番目のケースではコントローラーですが、最初のケースでどのように動作するかわかりません。

4

3 に答える 3

5

Interface BuilderがIBOutletsの弱参照を作成する理由は、次のとおりです。

IBは、ビューがそのスーパービューによって保持されることを知っています。したがって、ビューのツリー内のオブジェクトは、ルートオブジェクト以外の強力な参照を持つ必要はありません。ビューコントローラは、この強力な参照をメインviewプロパティに保持します。

これで、ビューがアンロードされると(少なくとも、iOS 5まで)、UIViewControllerのviewプロパティがnilに設定され、メインビューが解放されます。このスーパービューのサブビューへのIBOutletsが強力な参照である場合、それらはビュー階層の一部をメモリに保持します。これは望ましくありません(これらの孤立したビューにアクセスするときに混乱を招く可能性があります)。

于 2013-02-07T22:10:34.370 に答える
4

何かがこれらの要素への強力なポインタを維持する必要がありますよね?でもなに?

正解です。オブジェクトが存在するには、オブジェクトへの強い参照が少なくとも1つ必要です。UIのルートレベルオブジェクトへの強力な参照のみが必要です。これより下のオブジェクトは弱くなる可能性があります(親オブジェクトが子を所有するため)。その.xibファイル所有者と調整されたファイルはあなたのためにこれを行ったでしょう。

ファイルの動作については、このドキュメントをxib参照してください。具体的には、このスニピット:

通常、最上位オブジェクトへの強力な参照が必要であり、それらの割り当てが解除されないようにします。オブジェクトは親によって所有されているため、グラフの下の方にあるオブジェクトへの強い参照は必要ありません。また、強い参照サイクルを作成するリスクを最小限に抑える必要があります。

実用的な観点から、iOSおよびOS Xでは、アウトレットは宣言されたプロパティとして定義する必要があります。ファイルの所有者からnibファイル(またはiOSではストーリーボードシーン)のトップレベルオブジェクトまでのアウトレットを除いて、アウトレットは一般的に弱くする必要があります。したがって、作成するアウトレットは通常、弱いはずです。

于 2013-02-07T21:53:23.223 に答える
1

受け入れられた答えにもかかわらず、これはあなたがコードでそれを作ることができる方法です:

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,100,20)]; // strong ref
label.text = @"some text";
[self.view addSubview:label]; // strong ref from superview
self.label = label; // weak ref
// Now you can do `label = nil;`

これは、XIBからロードするときのポイントです。それがあなたの弱い財産に割り当てられたとき、すでにlabel 監督権を持っています。

于 2013-02-07T22:12:44.137 に答える