2011-02-04 8 views
2

なぜ私は(私のdeallocメソッドの内部で)使うのですか?なぜself.myInstance = nilではなくmyInstance = nilですか?

  1. [myInstance release]代わりの[self.myInstance release]
  2. myInstance = nil代わりのself.myInstance = nil

我々はself.myInstance = [[[AClass alloc] init] autorelease]代わりのmyInstance = [[[AClass alloc] init] autorelease]を使用していますが?

これらの方法は、私がウェブ上で見てきた多くの例に由来しています。

+0

サイトを検索してください。この質問は以前何度も出てきました。 –

答えて

1

1 [myInstanceの解除]の代わりに[self.myInstanceリリース]

前者を好む。

戻り値self.myInstanceは、サブクラスがメソッドmyInstanceをオーバーライドしたときの実装によって定義されます。 dealloc中に構築されたオブジェクトのインターフェースの振る舞いには興味がありません(サブクラスがあなたのivar以外のものを上書きして返すかもしれないので)。

deallocに興味のあるものは、オブジェクトが破棄される前に所有している参照を解放しています。サブクラスはmyInstanceをオーバーライドしている場合、それは可能性:

a)のサブクラスで宣言さIVARを(返す)すでに新規を返すことが

または

b)のオーバーライドの実装をリリースしているなら、オートレリースされたオブジェクトを作成しました

aまたはbのいずれかが過剰リリースおよびクラッシュにつながる可能性があります(他のすべてが正しく保持または解放されていると仮定します)。これはなぜそれを解放した後にivarにnilを割り当てるべきなのかを示唆しています。

これは、オブジェクトの復活をトリガする方法の古典的な例です。オブジェクトの復活は、getter/setterの実装がすでに割り当て解除された後でその状態を再作成するときに発生します。最も攻撃的でない副作用は無害な漏れを引き起こすであろう。

2)myInstanceの= nilの代わりに再びself.myInstance =ゼロ

は、前者を好みます。

正式な応答は、#1の応答とよく似ています。正当な理由、副作用、危険性もここに当てはまります。

これを処理する最も安全な方法は、直接IVARにアクセスすることです:再現するのは難しいかもしれ本当に厄介な副作用(クラッシュ、リーク、復活)が存在する可能性があるので

[myInstance release], myInstance = nil; 

を。

これらの危険性は簡単に回避でき、コードははるかに維持しやすくなります。一方で、プログラムを使用するときに副作用が発生した場合、可能な限りどこでも(再)使用を避けることになります。使用

myInstance = nil 

代わり

self.myInstance = nil 

では、myInstanceのが保持している場合(のUIViewControllerのサブクラスでviewDidUnloadメソッドを言うのコンテキストで)正しくないことを

幸運

1

self.myInstance =を呼び出すと、自動生成セッターメソッドが使用されます。 [self.myInstance release];を呼び出すと、getterメソッドによって返されたオブジェクトのreleaseが呼び出されます。それはあなたのプロパティがどのように設定されたかによって異なります(保持、割り当て?)。あなたの質問に必ずしも正解または間違った答えがあるわけではありません。なぜなら、それは問題の財産に依存しているからです。私はObjective C propertiesを読んで、このようなことをより良く感じることをお勧めします。

そして、myInstanceのがアサインで宣言された場合を除き、あなたはあなたがself.myInstanceとオフはるかに良いと思いますself.myInstance = [[AClass alloc] init]呼び出すのは嫌だ= [[[AClass alloc] init] autorelease]

1

これはあなたがインターフェイスで定義されたプロパティに依存します。あなたがプロパティを保持して定義した場合たとえば:

[property release]; // releases previous property 
property = [nil retain]; // [nil retain] returns just nil 

self.property = [[A alloc] init];と非常に同じことを:

@property (nonatomic, retain) NSObject *property; 

それが等しいため、あなたは、deallocメソッドでは、単にself.property = nil;を使用することができます。これはproperty = [[A alloc] init];プロパティの場合に

[property release]; // releases previous property 
property = [[[A alloc] init] retain]; 

に等しく保持されません。

Here'sアップルプロパティガイドフォーム。

+0

@kovpasにリンクが切れる。それはこれですか?https://developer.apple.com/library/mac/documentation/cocoa/conceptual/codingguidelines/Articles/NamingIvarsAndTypes.html – Cong

+0

@congliuありがとうございます! – kovpas

0

実際

self.myInstance = [[AClass alloc] init]; 

を使用するself.myInstanceがALLOCとともに+1を保持/ initが+1を保持するに導くセッターメソッドを使用している原因と、メモリリークにつながります。だからあなたは保持カウント+2を得るでしょう;

0
... = self.myInstance 

self.myInstance = ... 

実際にサブルーチンやメソッドは、getterとsetterの呼び出し、あなたはこれらのサブルーチンを定義する方法に応じた、またはObjective Cのプロパティがそれらを作成していている、ほとんど何でも行うことができます。

プロパティを保持する場合、サブルーチンは保持カウントで再生することがあります。あなたがゲッターとセッターを自分で作っている場合は、あなたの家のライトをコントロールして、ゼロセットがない場合はオンにし、ゼロまたはゼロに設定する場合はライトをオフにすることができます。でもによって設定することができ、 "インスタンス" という名前のバッキング変数があるように必要はありません)

instance = ... 
1

注意myInstanceがオブジェクトを指す場合、それはリークされます。

関連する問題