2

これが私の状況です。UIViewControllerおそらく以下に示すように、サブビューの階層を管理するがあります。

階層を表示

このビューはから作成されます.xib。topViewの各サブビューへのアクセスを維持できるようにしたいのですが、たとえば、次のように言うことができるように、それぞれへのポインターが必要です。

[button1 setText:@"Hello!"];

通常、これを行うには、Interface Builderを使用してアクセスしたい各要素を接続し、次のようなヘッダーを作成します。

@interface MyViewController : UIViewController
{
    __weak IBOutlet UIView *view;
    __weak IBOutlet UILabel *label;
    __weak IBOutlet UIButton *button1;
    __weak IBOutlet UIButton *button2;
}

@end

これらのインスタンス変数は__weak問題ありません。これは、ビューコントローラーがそれらを「取得」するまでに、ビューコントローラーのルートビュー(紛らわしいことに、クイックダイアグラムで「topView」とラベル付けしたもの)によって既に所有されているためです。実際、ルートビューが解放されたときに、これらの参照を弱くしたいので、すべてのサブビューも解放する必要があります。素晴らしい。

しかし、UIの新しい要素、おそらくカスタムボタンを、完全にコードで作成したいとします。CustomViewClassこの要素を、からサブクラス化される要素と呼びますUIViewCustomViewClass私が作成するインスタンスはと呼ばれcustomButtonます。私のビューの他のサブビューと同様に、私はそれと対話できるように「アクセス」したいと思いますcustomButton。ただし、他のサブビューと同様に、customButtonそのスーパービューが所有することはわかっています。そのようにする必要があります。繰り返しになりますが、ビューがリリースされるたびにリリースされるようにします。__weakこれにより、このビューをビューコントローラーのインスタンス変数またはプロパティとして宣言する必要があると思います。そうしよう:

@interface MyViewController : UIViewController
{
    __weak IBOutlet UIView *view;
    __weak IBOutlet UILabel *label;
    __weak IBOutlet UIButton *button1;
    __weak IBOutlet UIButton *button2;
    __weak CustomViewClass *customButton;
}

@end

次に、私の実装では:

@implementation MyViewController
- (void)viewDidLoad
{
    [super viewDidLoad];

    customButton = [[CustomViewClass alloc] init];
    [[self view] addSubview:customButton];
}
@end

おそらくすでにお気づきかもしれませんが、これは機能せず、コンパイラは起動するために警告をスローします。何かのようなもの:

Assigning retained object to weak variable; object 
will be released after assignment

私は現在、この種の警告を非常に貧弱なスタイルでかわしています。

@implementation MyViewController
- (void)viewDidLoad
{
    [super viewDidLoad];

    CustomViewClass *customButtonLocal = [[CustomViewClass alloc] init];
    [[self view] addSubview:customButtonLocal];
    customButton = customButtonLocal;
}
@end

そうすれば、私は欲しいものを手に入れることができます:

  1. 画面上のCustomViewClassのインスタンス...
  2. ...ちょうど1人の所有者、その監督...
  3. ...そして長引く変数はありません(customButtonLocalはブロックが終了した直後に解放されます)。

しかし、これはこれを行うための「正しい」方法ではありません。それで、最後に、私の質問:

この仲介者の回避策を使用せずに、プログラムで作成されたこの変数をどのように割り当ててインスタンス化する必要がありますか?__weak

4

1 に答える 1

2

強力CustomViewClass *customButtonな参照を作成します。

通常、サブビューの変数を宣言する理由__weak IBOutletは、これらのリンクの存在が所有権を意味するものではないためです。サブビューは、NIB/ストーリーボードからインスタンス化されたオブジェクトによって所有されます。そのオブジェクトを直接所有し、その依存オブジェクトも間接的に所有します。

これcustomButtonは別の話です。プログラムで作成するため、NIB/ストーリーボードはそれを所有しません。したがって、それを参照する必要が__strongあります(これは、ARC修飾子がない場合のデフォルトです)。

于 2012-07-03T15:50:02.157 に答える