2011-11-01 1 views
6

、私は次のことを見てきました:IBOutlet Workのreadonlyプロパティはありますか?それは好ましいでしょうか?私は継承してるコードで

@property (readonly) IBOutlet UIImageView * bgImage; 

私は次のように保持メモリモデルを期待する:

@property (readonly, retain) IBOutlet UIImageView * bgImage; 

私がなぜ最初のプロパティの定義混乱しています問題を起こさずに動作します。誰もがこのための説明を考え出すことができる場合、私は感謝し

-(void)dealloc 
{ 
    [_bgImage release]; 
    [super dealloc]; 
} 

はまた、releaseはあなたのように期待するかもしれないようにdeallocでもあります。私は元の開発者と話し、彼はメモリモデルの中でretainを省略した理由(より不必要であると思われる)より簡潔なコードを書くことを試みていました。

それは(何のセッターは使用しないために、このようにデフォルトの割り当てメモリモデルには違いはありません)読み取り専用であるため、IBOutletは、基本的にはIVAR IBOutlet文のように扱われるのだろうか。

IBOutletが変化することが予想されることはありません場合は、なしメモリモデルでReadOnlyプロパティを使用してしまうと、実際にプロパティを定義するための望ましい方法は?

答えて

7

は、iOS上のペン先のローダはペン先にオブジェクトを作成し、それらを自動解放します。アウトレットへの接続を確立すると、setValue:forKey:が使用され、そのキーのセッターメソッドが呼び出されます。 IBOutletreadonlyプロパティのようなセッターが定義されていない場合、オブジェクトは割り当てられる前にとなり、が保持されます。 (これはリソースプログラミングガイドのManaging Nib Objects in iOSの言い換えである。)

コンセントがretainまたはassignとして宣言されているかどうかだから、実際には、もう一方の端のオブジェクトがアウトレットを持つオブジェクトが所有するです。 setterメソッドによって保持されるか、セッターが見つからない場合はsetValue:forKey:によって保持されます。 2番目のケースでは他に可能な所有者がないので、コンセントを持つオブジェクトを所有者と見なすことができます。したがって、ペン先のオブジェクトはdeallocで解放する必要があります。

このメモリ条件は、プロパティの属性をretainに変更することで明示的に指定する必要があります。* readonlyが違いを生じないかどうか(ただし、下記を参照)。概念的には、はい、オブジェクトは読み込み専用なので、明示的にそれをオブジェクトとしてマークするかどうかは、それがIBOutletであることによって適切に文書化されているかどうかによって異なります。

UPDATE: Paul.sさんのコメントは、以下の簡単なテストを行うために私を促しました。私は、そのallocretainrelease、およびautorelease呼び出しをログに記録UIViewサブクラスを作成したペン先にそれのインスタンスを立ち往生し、プロパティを経由してアプリデリゲートにIBOutletを与えました。

参照カウントアクティビティを手作業で集計すると、プロパティが(readwrite, assign)の場合、インスタンスはネット0でカウントされます。プロパティが推奨された方法で宣言されたときには+1 +1であり、であり、でものときは(readonly, assign)でした。これはすべて予期どおりです。(readwrite, assign)の場合、割り当てを行うセッターが接続の作成に使用され、保持は行われません。それがreadonlyであるとき、接続機構はそれ自身の保持を行うことに転じる。

最も興味深いことに、このビューの背景色を(readwrite, assign)と宣言されたプロパティで変更してアプリをクラッシュしようとしたとき(つまり、おそらく割り当てが解除されたとき)、retainの最後の呼び出しがポップアップしていました。

Appleの推奨に従ってください。彼らは裏で何が起こっているのかを知っていますし、バグは許されません。

(別のことは、いつものように、絶対参照カウントを心配することはあまり役に立ちません。カウントは2ダースの呼び出しで1点で最大6回まで変化しましたretainreleaseに - あなただけ保持し、あなたが直接原因となるリリースを心配する必要があります)


*もちろん、これはARCの下に変更。私が言い換えた情報は、その章の「レガシー・パターン」セクションにあります。 ARCでは、トップレベルでない限り、はweakであることが推奨されます。その場合は、strongである必要があります。このようにすると、ビュー階層(ビューを保持しているビュー)に依存して自分自身を維持することになります。

+0

'コンセントがretainまたはassignとして宣言されているかどうか、反対側のオブジェクトはコンセントでオブジェクトに所有されています(これはあまり明確ではありません)。これは' readonly'に設定されている場合のみですか? '(assign、readwrite)'だった場合は、保持していないセッターが使用され、 'retain'は使われませんでしたか? - 私はそれがちょっとあいまいなあなたの答えの唯一の部分だと言います。 –

+0

私はそう思っています...それは確かに言うようです。 –

+2

@ Paul.s:私の更新を見てください - 参考活動を手作業で数えることにしました。その結果は有益だと思います。 –

2

プロパティの代わりにIBOutletインスタンス変数を作成すると、Xcodeがdeallocなどのリリースを自動的に作成するというAppleのバグが報告されています.iOSアプリケーションのXcodeは、IBOutletのリリースが常に正しいかどうかを判断します。

私はプロパティIBOutletを読んでいるとは言いません。つまり、それらはreadwriteとして文書化されていますが、ほとんどの場合、(ほぼ常に)IBOutletは概念的には読み込み専用です。当然のことながら、最初に設定するには、それらを読み書きする必要があります。

+0

パブリックインターフェイスでは '@property(nonatomic、readonly)'、クラス拡張では '@property(nonatomic)IBOutlet'を宣言できます。 –