2

さて、オブジェクトを割り当てずにかなりの量のコードを記述した場合、メモリはどこに行きますか?

たとえば、持っているのではなく

UIImage *myImage = [UIImage imageNamed:@"image.png"];
imageView.image = myImage;
[myImage release];

私は持っていた

imageView.image = [UIImage imageNamed:@"image.png"];

私のすべてのコードを通して。2番目の例では、メモリで何が起こっているのかわかりません。私はまだ学習中であり、オブジェクトを割り当てることなく、アプリ全体で2番目の例を使用して多くのコードを記述しました。シミュレーターでは常に正常に動作しましたが、実際のデバイスはメモリを処理できず、クラッシュします。メモリ管理に関するすべてのチュートリアルでは、作成したオブジェクトを解放するという意味でそれについて説明していますが、オブジェクトを作成したことがないため、行き詰まっています。

4

3 に答える 3

4
UIImage *myImage = [UIImage imageNamed:@"image.png"];
imageView.image = myImage;
[myImage release];

ダブルリリースを行いました。[UIImage imageNamed] は自動解放されるため、オブジェクトを明示的に解放する必要はありません。リリースされていないオブジェクトが原因ではなく、二重リリースが原因でアプリがクラッシュした可能性があります。

簡単な経験則、iPhone のココアでのリリース/自動リリースの混乱を読んでください。

ルールは簡単です。割り当て、コピー、または保持する場合、リリースするのはあなたの責任です。そうでない場合は、そうではありません。ただし、オブジェクトが存在することに依存する必要がある場合は、保持 (およびその後解放) する必要があります。


その他の例:

imageView.image = [UIImage imageNamed:@"image.png"];

上記のコードは有効です。リリースする必要はありません。ただし、このような未リリースのオブジェクトで多くの直接割り当てを使用する場合:

foo.bar = [[SomeClass alloc] initWithSomething:@"Init"];

autorelease を追加することで、簡単に修正できます。

foo.bar = [[SomeClass alloc] initWithSomething:@"Init"] autorelease];

または、長くても間違いなくより適切な方法が必要な場合 (オブジェクトがいつ解放されるかを制御しているため):

SomeClass *tempVar = [[SomeClass alloc] initWithSomething:@"Init"];
foo.bar = tempVar;
[tempVar release];
于 2011-07-25T03:44:54.357 に答える
2
imageView.image = [UIImage imageNamed:@"image.png"];

この行は素晴らしく、正しいです。

メソッドの実装では、 new にimageNamed:メモリを割り当て、 newをそのメモリにUIImageインスタンス化し、それを返す前にそれを返す場合があります。自動解放プールは、コードの実行後にドレインされ、何も保持されていない場合はイメージ オブジェクトの割り当てが解除されます。UIImageautorelease

では、「記憶はどこへ行くのか?」自動解放プールに移動します。しかし、本当に、あなたが電話しない限り、気allocにする必要はありません。copy...retain

マニーが指摘しているように、あなたの最初のスニペットはオーバー リリースであり、正しくありません。

于 2011-07-25T03:50:52.600 に答える
1

変数の宣言とメモリ/オブジェクトの割り当てを混同しています。上記の両方の場合のコードの重要な部分は、実際には次のとおりです。

[UIImage imageNamed:@"image.png"];

このコードは、多くのことを行う UIImage クラスのクラスメソッドをたまたま呼び出します。これらのことの 1 つは、UIImage オブジェクトの割り当てと初期化です。最初の例では、この割り当てられたオブジェクトを という変数に格納しましたmyImage。次に、光沢のある新しいオブジェクトを別の (クラス) 変数 `imageView.image' に移動しました。

UIImage *myImage = ...

あなたが与えた2番目の例では、この割り当てられたオブジェクトを変数に格納していますが、この場合は中間代入をスキップし、オブジェクトをクラス変数に直接格納しましたimageView.image

imageView.image = [UIImage imageNamed:@"image.png"];

変数とオブジェクトを考える 1 つの方法は、それらを家に例えることです。このシナリオでは、変数はあなたの住所であり、オブジェクトはあなたの家です。何人かがあなたの住所を知っている可能性がありますが、何人であっても、訪問することを選択すると、同じ家に行きます. したがって、あなたの例myImageimageView.imageは、同じ家、またはオブジェクト、UIImage のインスタンスを指すアドレスです。あなたの例では、他の目的で使用していない限り、実際に中間変数を作成する必要はありません。

クラッシュに関する限り、Apple のメモリ管理ガイドを読む必要があります。しばらく時間がかかるかもしれませんが、オブジェクトの保持と解放に関して Apple が従う標準に慣れるでしょう。XCode 4.2 の新しい自動参照カウントは、これらの問題の多くを軽減しますが、独自の学習曲線もあります。しかし要約すると、所有していないオブジェクトを解放しているため、クラッシュが発生しています。imageNamedUIImageのクラス メソッドは、そのクラスの自動解放されたインスタンスを返します。コードで別のリリースを送信する必要はありません。これが、プログラムのクラッシュの原因となる可能性があります。

于 2011-07-25T03:50:37.640 に答える