7

どこかで私はそれを読んでいました-メモリ不足の警告とすべてのサブビュー(=ペン先全体、私は思う)で非表示のビューを放棄することに関して、あなたはそれをするべきです:

-(void)dealloc {
    [anView release], anView = nil;
    [someImageView release], someImageView = nil;

    [super dealloc];
}

それよりも

-(void)dealloc {
    [anView release];
    [someImageView release];

    [super dealloc];
}

リリースを呼び出した後、これらのポインタをnil(=「オブジェクトなし」)に固定する理由は何ですか?推測させてください:他の方法で何らかの理由でビューを保持している可能性があります(これが発生する可能性がある場合の例はありますか?)、didReceiveMemoryWarningが発生し、現在表示されていないnib + view全体を解放します(つまり、マルチビューアプリで)。ユーザーがそのビューをもう一度見たいと思ったら、すぐにペン先をもう一度ロードしてから、すべてのビューをロードし、コンセントを接続して、BANG!他の保持されたビューは、メモリブリックのどこかにポインタがない状態でハングしているため、アプリがクラッシュするまで、大量のメモリリークが発生します。

正しい/間違っていますか?

4

5 に答える 5

14

原則は UIView よりも一般的です。-release実際、Objective-C/Cocoaメソッドよりも一般的です。malloc()C /free()メモリ関数でも有効です。

オブジェクトやメモリ ゾーンが不要になったら、まず解放/解放します。次に、二度と使用しないようにするためnilに、オブジェクトまたはNULLメモリ ポインターに a を割り当てることによって、このオブジェクトまたはメモリ ゾーンにアクセスする手段をクリアします。

于 2009-04-30T08:37:08.460 に答える
11

何らかの理由で他の方法でビューを保持できた可能性があります

自分自身を呼び出していない限りdealloc、保持カウントがゼロになったときにのみ呼び出されます。

Objective-C では、メッセージをnil「オブジェクト」に送信することは (多くの場合) 完全に問題ないことに注意してください。そうしてもプログラムは停止しませんが、メッセージは単に無視されます。ただし、解放されたオブジェクトにメッセージを送信することはできず、クラッシュが発生します。

したがって、次のようにするとエラーが発生します。

[anView release];
[anView doSomething];

しかし、これは実際には問題ありません。

[anView release];
anView = nil;
[anView doSomething];

好みの問題ですが、上記の場合、doSomething が実行されない理由を考えるよりも、実際にはプログラムをクラッシュさせることを好むかもしれません...

Apple のIntroduction to The Objective-C 2.0 Programming LanguageのSending Messages to nilも参照してください。

于 2009-04-30T09:55:25.820 に答える
4

-dealloc メソッドは、オブジェクトが解放されたときに呼び出され、その後オブジェクトの他のメソッドは実行されません。したがって、インスタンス変数を nil に設定しても、そのオブジェクトの外では何の効果もありません。

クラスの別の場所で (setter を使用せずに) オブジェクトを解放する場合は、インスタンス変数を nil に設定して、他の場所のコードがそのアドレスにメッセージを送信しないようにすることが重要です。

于 2009-04-30T21:03:07.993 に答える
2

私はこのパターンをよく使います:

- (void) showHelp: (id) sender
{
    if (helpController == nil)
    {
        helpController = [[HelpController alloc] initWithNibName: @"Help" bundle: [NSBundle mainBundle]];
    }
    [self presentModalViewController: helpController animated: YES];    
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
    [helpController release];
    helpController = nil;
}

モーダルまたは「一時的」なビューコントローラーを割り当てるほとんどすべての場所。このようにして、再び必要になった場合はハングアップしますが、メモリが少なくなると消えます。

于 2009-04-30T17:07:07.687 に答える
1

明示的なリリースを実行して nil に設定するのではなく、アクセサーにプロパティが関連付けられている場合は、より簡潔な方法として以下を実行します。

- (void) dealloc
{
    self.retainedProperty1 = nil;
    self.retainedProperty2 = nil;
    self.copiedProperty = nil;
    self.assignedProperty = nil;
}

このようにして、合成されたコードがリリースを処理するため、繰り返しの少ないコードを作成できます。

編集:プロパティを読み取り専用にすることはできないことを指摘する必要があります。そうしないと、明らかな理由でコンパイラエラーが発生します:)

于 2009-05-12T22:31:26.393 に答える