2012-03-26 5 views
1

私はdealloc()メソッドとviewDidUnload()メソッドについて簡単に質問しています。私は多くのコード例に気付き、人々はさまざまなことをするようです。iPhone deallocとviewDidUnload問題

また、ARCはオプションではないと付け加えます。

(1)IBOutletsを含むdealloc()メソッドですべてのプロパティをnilに設定する必要があります。たとえば、インスタンス変数[_myArrary release]を解放し、self.myArrary = nilを設定する必要があります。

(2)viewDidUnloadでは、すべてのIBOutletをnilに設定する必要があります。また、viewDidLoadで作成されたものもすべて設定する必要があります。しかし、myStringについては、viewDidLoadが呼び出された後、別のメソッドで初期化されています。私はそれを無しにするべきですか?

私はそのように宣言いくつかのプロパティを持っている場合:

@property (nonatomic, retain) IBOutlet UITableViewCell *myTableCell; 
@property (nonatomic, retain) IBOutlet UILabel *myLabel; 
@property (nonatomic, retain) NSArray *myArrary; 
@property (nonatomic, retain) NSString *myString; 

I synthesize them as such: 

@synthesize myArrary = _myArrary; 
@synthesize myTableCell; 
@synthesize myLabel; 
@synthesize myString; 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    _myArrary = [NSArrary alloc] initWithObjects:@"testObject", nil]; 
} 

- (void)viewDidUnload 
{ 
    self.myArrary = nil; 

    self.myTableCell = nil; 

    self.myLabel = nil; 

    [super viewDidUnload]; 
} 

- (void)dealloc 
{ 
    [_myArray release]; 

    [super dealloc]; 
} 

答えて

4
  1. オブジェクトが割り当て解除されると、あなたはされませんので、あなたがのdeallocでnilにプロパティ/変数を設定した場合、それは問題ではないはずとにかくそれらにアクセスすることができます。やって、特性を保持してself.varname = nil;

    は、両方の変数を解放し、ゼロに設定します。多くの人がそれらを解放することを好む、私は一貫性のためにnilにretainプロパティを設定することを好む。

  2. ビューでは、ビューを再ロードするときに不要で、再作成されるものを解放してnilに設定する必要があります。これは厳密なルールではありませんが、できるだけ多くのメモリを利用できるようにすることをお勧めします。あなたの文字列がviewDidLoadで再作成され、ビューが再びロードされるまでアクセスする必要がない場合は、おそらく解放する必要があります(安全のためにnilに設定します)。

    viewDidUnloadがdeallocより前に呼び出されるとは限りません。ですから、たとえリリースされていてもviewDidUnloadでnilに設定されていても、すべてのプロパティ/変数を解放する必要があります。あなたのクラスの割り当てが解除されたときに漏れないことを確認するためには、そのコードのためのあなたのdealloc機能は次のようになります。nilにそれらを設定する

    - (void)dealloc { 
        [myTableCell release]; 
        [myLabel release]; 
        [_myArray release]; 
        [myString release]; 
    
        [super dealloc]; 
    } 
    

    も許容されていますが、合成されたセッターを使用する場合のみこれは変数を解放するためです。

    self.myLabel = nil; 
    

    は大丈夫ですが、

    myLabel = nil; 
    

    は漏れやすいです。一般的に

+0

myTableCell、myLabel、およびmyStringはインスタンス変数を持たないプロパティで、[myTableCell release]と言うことはできません。[self.myTableCell release]が間違っていることがわかりました。 – Vikings

+0

実際、 '[myTableCell release]'は正しいです。これらのイナールは暗黙のうちに作成されます。 –

+0

これらを使用しているコンパイラのバージョンによっては、すべて有効である可能性があります。 @synthesizeはあなたのためにivarを作成します - あなたは 'myArray' ivarの名前を' _myArray'に変更しましたが、他のプロパティの名前はivarsと同じです。さらに、あなたが 'dealloc'にいるなら、あなたはマルチスレッドでない限り' [self.myTableCell release] 'で逃げることができます...しかし、これは複雑すぎます - 今のところsetterとgetterを使用してください以前に説明したように、メモリ管理ガイドラインを徹底的に読んでください...またはARCを使用してください。これはiOS4デバイスでも利用可能です。 – ikuramedia

2

、あなたはあなたがあなたのviewDidUnloadViewControllerはその間にdeallocedされていない場合viewDidLoadで再現することができます何かをリリースしたいです。

deallocでは、ViewControllerがまだ所有しているものをすべてリリースする必要があります。最初にviewDidUnloadが呼び出されたと想定することはできませんので、守りましょう。

nilにメッセージを送信しても害はありませんが、自分が所有していないオブジェクトにリリースを送信したり、所有しているオブジェクトに複数回送信したりすることは害です。

あなたのプロパティは合成されているので、自分でreleaseを送信する必要はありません。セパレータを使用して、余分な保持はどこにも追加していないと仮定すると、それらをnil(self.property = nil)に設定するだけです。

N.B. viewDidLoadでは、新しく作成したオブジェクトを、プロパティが合成したiVarに明示的に割り当てました。これをしないでください! 別のオブジェクトがインスタンス化とプレゼンテーションの間でプロパティを設定している場合は、がリークします。それが正しいことであることを知っているときにのみ、_ivarを使用してください。あなたはすべての辺のケースを世話しました。

TL:DR - viewDidUnloaddeallocの両方で使用self.property = nil、決してあなたはそれがすでにnilであるか、前の値を解放する用意があることを最初にチェックしていない限り_ivarに新しいオブジェクトを割り当てます。

+0

self.myArray = [NSArrary alloc] initWithObjects:@ "testObject"、nil]は、Xcodeで解析したときのリークを示します。 [NSArray arrayWithObjects:@ "testObject"、nil] \ – Vikings

+0

'selfArray = [[NSArray alloc] initWithObjects:@" testObject "、nil] autorelease]'またはより単純に 'selfArray = [NSArray arrayWithObjects:@" testObject "、nil]' – ikuramedia

+0

応答のためにありがとう、あなたはなぜあなたが邪魔にならないのかを精緻に説明することができますか?私は配列や他のオブジェクトを設定するときにこれをやっている多くの人々を参照してください。 – Vikings

関連する問題