2009-07-31 15 views
33

だから私はこれらすべての質問をすべて理解したと思った。そして突然、私は理解できないエラー(クラッシュ)を受けます。その後、クラッシュを修復するための研究をした後、私はこれらの重要な領域が多少間違っていると私が思っていたことすべてに気付きます。リリース、Dealloc、および自己参照

以下に8つの質問があります。誰かが答えることを期待してそこで撃つつもりです。これらの回答が私の理解を大いに助けてくれるでしょう。あらかじめありがとう!

Q1)オブジェクトのReleaseがnilの場合は、そのオブジェクトに対してReleaseを呼び出すことはできますか?これは無害でなければなりません。

Q2)参照が解放され、参照カウントが0の場合、オブジェクトに対してReleaseを呼び出すことはできますか?

Q3)それを解放してからnilへの参照を設定する必要がありますか?それをゼロに設定しないとどうなりますか?

Q4)実際にはnilとNULLの間に違いがありますか、読者/開発者がオブジェクトタイプを知るのを助ける意味的なことですか?

Q5)プロパティを使用するには、「セルフ」ポインタを使用する必要がありますか?

Q6)インスタンス変数を使用するには、 'Self'ポインタが使用されていないことが必要ですか?

Q7)いつもプロパティの代わりにインスタンス変数を使用したいのですか?私は値の型のデータメンバーが解放されていると保持されていないので大丈夫だと思います。

Q8)dealloc関数内からオブジェクトのdeallocを呼び出す必要がありますか? 多くの例で、私はReleaseが呼ばれているのを見ましたが、Deallocではそうではありません - そのようなチュートリアルは間違っていますか?

+0

ニースq。私はちょうど私が答えたいと思っていなかったいくつかの新しい質問を見つけました。 – typeoneerror

答えて

11

おそらく、この質問を複数の異なる質問に分割する必要がありますが、私は噛んでしまいます。

  1. はい、nilに送信されたメッセージはすべてノーオペレーションです。
  2. いいえ。参照カウント0のオブジェクトが破棄されているか、またはすぐに破棄され、送信されたメッセージがクラッシュするか、例外的に例外が発生します。
  3. 状況によって異なります。 -deallocのものをリリースしている場合は、おそらくそうではありません。特定のメソッドにスコープされているオブジェクトの場合は、おそらくそうではありません。それが再使用される象牙であれば、私は「はい」と言います。最初の2つのケースでは、ポインターをnilに設定しないと何も起こりません。なぜなら、通常はそれらのポインターにはもうアクセスできなくなるからです。ただし、最後のケースでは、引き続き割り当てられたメモリを指しているポインタにアクセスできます。メッセージを送信したり、逆参照しようとすると、アプリがクラッシュします。
  4. これらは両方とも0に等しい。慣例により、nilはオブジェクトポインタに使用され、NULLは他のポインタに使用されますが、それらを混合しても問題は発生しません。
  5. getter/setterプロパティを呼び出す場合は、yesを入力します。あなたがivarにアクセスしたいのであれば、直接カプセル化します(珍しい)、いいえ。
  6. いいえ、self->ivarの構文を使用してインスタンス変数にアクセスできます。実際、ivarと入力すると、コンパイラは暗黙的にself->逆参照を追加します。
  7. ここに何を意味するのかわかりません。
  8. -deallocに電話する必要があるのは、[super dealloc];を自分の-deallocメソッドで呼び出すときだけです。他のオブジェクトの場合は、常に-releaseを呼び出す必要があります。
+0

(2)NSZombieEnabledに言及する必要があります。これは、デバッグのallocの問題を簡単にします。 – diciu

+0

"easy"は強い言葉です!私は "より簡単に"言うだろう。 –

19

A1)[nil release]は(何もしません)、彼らが割り当てを解除されてきた後

A2)号は、オブジェクトを触れないでください結構です。リリース後にはnilに設定する必要があります。

A3)リリースされたポインタをnilに設定する必要はありませんが、ポインタがぶら下がっています(つまり、オブジェクトが有効かどうかはわかりません)。

A4)はnilとNULLを漏らすnilにプロパティを設定すると、多くの場合、基本となるIVARを解放するために使用されているので、これを行うに失敗すると、メモリを引き起こす可能性がありますので、技術的には同じであり、両方ともゼロです。

A5)はい、あなたはプロパティのself.somePropertyを使用する必要があり、それはちょうど方法

A6だった場合は、[self someProperty]を使用するのと同じように)自己は、基本的構造体であるので、あなたはそのようアイバーズにアクセスすることができます。self->someIvar。しかし、必要はありません。

A7)何らかの理由でsetter/getterメソッドを実行したくない場合。私はsetterがnil値を許可していないときにそれを使用し、変数を解放する必要があります。

A8)リリースが正しい時間で呼び出されると、deallocが自動的に呼び出されます。 deallocを直接呼び出すべきではありません([super dealloc]を除く)

+1

私は#5について混乱しています。私はビューコントローラで "ソーシャル"と呼ばれているnonatmic、保持された@プロパティを持っており、これらのステートメントは同じことを記録します:NSLog(@ "%@"、social); NSLog(@ "%@"、self.social);説明できますか、トム? – typeoneerror

+1

これは、両方のNSLog文が同じオブジェクトを出力しているからです。違いは、 'self.social'はオブジェクトを返すメソッドを呼び出すことであり、' social'はオブジェクトそのものです。ありがとう。 –

8

他の人は1〜6回は適切に回答しています。

(7)Appleは、initとdeallocの両方でインスタンス変数を直接使用することをお勧めします。主にこれは、オブジェクト(特にサブクラス化されている場合)がこれらのメソッドの両方で部分的にしか設定されていないためです。setters/gettersを呼び出すと、単純なアクション以外のものがあれば不正な動作になる可能性があります。一般的には、あなたのオブジェクトの中でゲッターを介してではなく、直接ivarにアクセスすることができます。そうするのが少し面倒です(iPhone上でのみ関連します)。一般的には、すべての場合にsetterを使うべきです。特に、オブジェクトがサブクラス化されている場合や、他のオブジェクトがそのプロパティを観察している可能性がある場合は特にそうです。

(8)deallocメソッド([super dealloc]を除く)をdeallocメソッドから呼び出すことはありません。別のオブジェクトの所有権を所有している場合は、その所有権を放棄する必要があります(releaseまたはautoreleaseを呼び出して)。必要に応じて、システムはオブジェクトに対してdeallocを呼び出します。しかし、自分でdeallocを呼び出すことは決してありません。 memory management rulesを読んでください(その9段落であり、理解するためには非常に重要です)。

+0

誰かが指摘したMMルールへのリンクを見つけました。間違いなくそれを読んでいる。 –

+0

Btw、これらの質問はすべて、私のリリースの考えが予期せぬクラッシュの後に壊れてしまったときに起こっています(アプリはnilへの参照を設定した後にクラッシュします)。なぜ地球上でnilへのポインタを割り当てるとアプリケーションがクラッシュするのですか? それ以来、私は別の参照へのポインタを割り当てるどこでも「自己」を使用してきました。 –

+0

参照が無効または解放されたオブジェクトの一部であった場合、nilへの参照を設定する唯一の理由はクラッシュします。 NSZombiesを有効にしてください。おそらく助けになります。 –

0

私は、Bをnilに設定しないとそのトリックをしなかったことを確認しました。 これで、Bコントローラを作成するときに(いつナビゲートしたいか)、nilをチェックしないでください。

はその代わり、私はその後、私はAさんviewDidAppear方法で、私はこのスレッドは現在閉鎖されていると信じて

B.

をリリース、そして、コントローラを作成し、B. に割り当て、Bを解放します。ありがとう!

0

A4)タイプが異なります。それらはすべてゼロですが、NULLはvoid *、nilはID、Nilはクラスポインタです。