Xcode 4.2で最初のiOSアプリの開発を開始し、「ユーティリティアプリケーション」テンプレート(FlipsideViewControllerに付属するテンプレート)でiOS 5.0をターゲットにしました。
ARCはコンパイル時の機能であるため、iOS 4とも互換性があるはずなので、アプリを4.3にターゲット化してコンパイルしてみました。そうすると、次のエラーが表示されます。
FlipsideViewController.m:エラー:自動参照カウントの問題:現在の展開ターゲットは自動化された__weak参照をサポートしていません
この行を参照しています:
@synthesize delegate = _delegate;
その変数は次のように宣言されます:
@property (weak, nonatomic) IBOutlet id <FlipsideViewControllerDelegate> delegate;
「弱い参照」はiOS 4ではサポートされていないことを理解していますが、最初は弱い参照を使用する理由がよくわかりません。また、使用を避けるために書き直す方法を理解できません。 ARCを引き続き活用しています(結局、iOS 4および5で動作するはずです?)
古いOSをターゲットにするには、プロパティ宣言でweak
の代わりにunsafe_unretained
を使用できます。ほとんどの場合、同じように機能します。 weak
は、ターゲットがなくなるとnil自体を参照しますが、unsafe_unretained
は、リンクを解除したときにリンク先のオブジェクトがダングリングポインターになる可能性を残します。後者は、手動メモリ管理でプロパティ宣言としてassign
を使用した場合と同じ動作です。
これは、保持サイクルを回避するために行います。これについては、私の答え here で言及しています。元のオブジェクトへの強力なポインタを戻す可能性のあるものへの強力なポインタは必要ありません。その後、何も適切にリリースされません。
安全性を高めるために弱参照のみを使用する場合は、新しいランタイム関数が使用可能な場合は手動で呼び出し、そうでない場合は__unsafe_unretained
変数の単純な割り当てにフォールバックします。
ZWRCompatibility.h は、これをいくらか単純化します。
Mike Ashの互換性ライブラリ PLWeakCompatibilty のおかげで、iOS 4.xでも__weakを使用できるようになりました。
構成は非常に簡単で、5.xを超える追加の考慮事項や労力は必要ありません。