6

自動合成されたreadonly&weakプロパティがあります:

@property (nonatomic, readonly, weak) KTWindowController* windowController;

合成された ivar を割り当ててから、配列に追加します。

_windowController = [KTWindowController controller];
[self addSubController:_windowController];

これは、デバッグ ビルドで正常に機能します。しかし、リリース (アドホック) ビルドでは、これはすぐに nil に_windowControllerなり、配列に nil を追加しようとして、アプリがクラッシュするという報告を受けました。

リリース (アドホック) ビルドの特定の設定 (最適化レベル?) によって、デバッグ ビルドと比較してこの動作が変わりますか?

この動作がデバッグ ビルドからリリース ビルドに変わるのは奇妙に思えます。しかし、私はこの動作を再現することができました。実際には理にかなっています - デバッグ ビルドで起こることと一貫性がない場合だけではありません。

推奨される回避策:

KTWindowController* windowController = [KTWindowController controller];
[self addSubController:windowController];
_windowController = windowController;

上記のようにローカル変数を使用する以外に、このような場合に推奨される回避策は何ですか?

4

2 に答える 2

1

プロパティをweakとして宣言すると、他のオブジェクトが所有権を処理することを約束します。弱いとはそういうことです。これに違反すると、悪いことが起こります。したがって、たとえば、次のように記述します。

KTWindowController* windowController = [KTWindowController controller];
[self addSubController:windowController];
_windowController = windowController;

あなたは義務を果たしています。強力な一時変数windowControllerは、このメソッド内で所有権をwindowController subController処理し、その後所有権を処理します。

あなたが書いたとき

 _windowController = [KTWindowController controller];

あなたは約束したことをしていませんでした。_windowController は弱いので、他の誰かが寿命を管理しています。でも、見てください!誰も生涯を管理していません!そのため、必要なときにいつでも弱い変数を自由に取り除くことができます。オプティマイザはリリース ビルドでこれを見て、次のように言います。

おい!この男は、他の誰も気にしない限り、このウィンドウ コントローラーが生きていようが死んでいようが構わないと言っています。人によっては!しかし、それは私の仕事ではありません。しかし、これを見てください: 彼は気にしないので、私はそれを作る必要はまったくありません! というか、とにかく作ったらすぐに捨てられる。

コンパイラは、あなたが望んでいたことを実行しているだけです。

これを弱いプロパティにしてよろしいですか? コードでこれを確認するたびに、プロパティが本当に弱いかどうかを確認するようにしています。多くの場合、とにかく強力なプロパティが必要です。

于 2013-04-02T20:25:08.387 に答える