1

私は他の誰かの iOS プロジェクトで作業しています。ARC は有効になっています (私の知る限り、常に有効になっています)。コードには、いくつかのビュー コントローラーのインスタンスを作成し、そのデリゲートを自分自身に設定してから表示するボタン プレス ハンドラーが散らばっています。

- (IBAction)keyButton:(id)sender {
    MyViewController *controller = [[MyViewController alloc] init];
    controller.delegate = self;
    [self.navigationController pushViewController:controller animated:YES];
}

MyViewController は、音楽キーを選択するためのスピン ウィジェットを表示します。選択したら、ユーザーは選択したキーを使用して音楽を作成するために押し戻します。これらは唯一のユーザー インタラクションであり、バックグラウンド プロセスなどはありません。

MyViewController.h ファイルでは、デリゲートは次のように宣言されています。

@interface MyViewController : UIViewController {
    id <ModuleUpdateDelegate> _delegate;
}

@property (nonatomic,strong) id delegate;

2 つの質問があります。

  1. 元の作成者が、ボタンを押すたびに MyViewController の新しいインスタンスを作成することを選択したのはなぜでしょうか?
  2. そのような各インスタンスの所有者は誰ですか? 【いつ】壊れるの?デリゲートへの強い参照を保持しているため、現在の実装は [ボタンを押すたびに] 強い参照サイクルを作成していますか?

私自身の本能は、デリゲートにプライベートな MyViewController * プロパティを作成することです。このプロパティは、最初にボタンを押したときにのみ読み込まれます。次に、一般的な推奨に従って、MyViewController のデリゲート プロパティを強力ではなく弱くします。しかし、私が言ったように、現在の実装は非常にユビキタスなので、最初にそれがどのように機能するかを理解せずに何かを変更するのは気が進まない.

どんな助けでも大歓迎です。

4

2 に答える 2

2

この場合、誰がMyViewController保持するかは問題ではなく、誰が のインスタンスを保持するかが重要ですMyViewController

投稿したコードでは、への強い参照MyViewControllerは によって保持されていself.navigationControllerます。がポップされるとすぐにMyViewController、保持カウントが 0 になり、解放されます。controller.delegate保持しない限りcontrollerサイクルはありません。

とはいえ、強力な後方参照 (デリゲートなど) には十分注意する必要があります。疑わしい場合は、Instruments を使用して保持サイクルまたはメモリ リークをチェックしてください。


私のアドバイス:注意してください。可能であれば、強いデリゲートを弱いデリゲートに変更します。今はリテイン サイクルがなくても、気付かないうちに簡単にリテイン サイクルを作成できます。

于 2015-11-25T00:30:05.880 に答える
2

デリゲート参照は慣例により弱いものです。

通常、オブジェクトを作成し、それへの強い参照を保持し、自分自身をデリゲートとして設定します。(そして、デリゲートへのポインターは弱いです。) そうすれば、強い参照は一方向にしかありません。

あなたの場合、コードは反対のことをしています。オブジェクト (MyViewController) がローカル変数で作成され、その後忘れられています。MyViewController クラスのデリゲート プロパティは強力です。したがって、MyViewController オブジェクトへの強い参照はありませんが、デリゲートへの強い参照はあります。

Jeffery が言うように、現在は保持サイクルを持っていないようですが、後で MyViewController オブジェクトへのポインターを保持する必要があると判断した場合は、保持サイクルを作成する可能性があります。

于 2015-11-25T01:02:03.810 に答える