2011-07-25 8 views
2

だから、オブジェクトを割り当てずにかなりのコードを書いたら、メモリはどこにありますか?例えば、むしろイメージを使ってメモリを管理する方法

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

を持つよりも

私はすべての私のコード全体

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

を持っていました。 2番目の例では、メモリで何が起こっているのかわかりません。私はまだ学んでいますし、アプリケーション全体で2番目の例を使って、オブジェクトを割り当てずにたくさんのコードを書いています。シミュレータでは常に正常に動作しましたが、実際のデバイスはメモリを処理できず、クラッシュします。メモリ管理に関するすべてのチュートリアルでは、作成するオブジェクトを解放するという意味でそのことについて話しますが、オブジェクトを作成していないので、私は立ち往生しています。

答えて

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

あなたはダブルリリースしました。 [UIImage imageNamed]はオートレリースされているため、オブジェクトを明示的に解放する必要はありません。あなたのアプリはおそらく二重リリースのためにクラッシュし、未リリースのオブジェクトのためではありません。

は親指の単純なルール、release/autorelease confusion in cocoa for iphone読む:

をルールは単純です:あなたはALLOC場合、コピーまたは保持、それは解放するためにあなたの 責任です。もしあなたがそうでなかったら、それはそうではありません。しかし、 がオブジェクトを頼りにする必要がある場合は、保持する必要があります(その後は がリリースされます)。


より多くの例:上記のコード

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

有効である、あなたはそれを解放する必要はありません。あなたは、このようなこの一つとして未発表のオブジェクトとたくさんの直接割り当てを使用している場合でも:

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

をあなただけ簡単に自動解放を追加することによって、それらを修正することができます

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

それとも、長いが、間違いなく、より適切なをしたい場合

SomeClass *tempVar = [[SomeClass alloc] initWithSomething:@"Init"]; 
foo.bar = tempVar; 
[tempVar release]; 
1

変数を宣言してメモリ/オブジェクトを割り当てるのは混乱しています。上記のどちらの場合も、コードの重要な部分は、実際にはこれです:

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

このコードは、多くのことをしてUIImageクラスのクラスメソッドを呼び出すために発生します。これらのうちの1つは、UIImageオブジェクトの割り当てと初期化です。あなたの最初の例では、この割り当てられたオブジェクトをmyImageという変数に格納しました。次に、光沢のある新しいオブジェクトを別の(クラス)変数、 `imageView.image 'に移動しました。あなたはまだあなたが仲介割り当てをスキップし、クラス変数imageView.imageに直接オブジェクトを格納され、この場合以外は、変数は、この割り当てられたオブジェクトを格納している得られた第2の例で

UIImage *myImage = ... 

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

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

クラッシュに関する限り、Apple's memory management guideにお読みください。しばらく時間がかかるかもしれませんが、オブジェクトの保持と解放に関してAppleが従う標準に慣れるでしょう。 XCode 4.2の新しいAutomatic Reference Countingである は、これらの問題の多くを軽減しますが、独自の学習曲線も持っています。要約すると、自分が所有していないオブジェクトを解放しているのでクラッシュしています。 UIImageのクラスメソッドimageNamedは、そのクラスの自動解放インスタンスを返します。あなたのコードで別のリリースを送る必要はありません。これがプログラムのクラッシュの原因です。

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

この行はすばらしく正確です。 imageNamed:方法の実装における

、それを返す前に、新しいUIImageにメモリを割り当て、そのメモリに新しいUIImageをインスタンス化し、その後autoreleaseできます。あなたのコードが実行された後にオートリリースプールが排水され、何も保持されていなければイメージオブジェクトの割り当てが解除されます。

「メモリはどこにありますか?」それはオートリリースプールに向かいます。しかし、実際には、allocまたはcopy...またはretainに電話しない限り、気にする必要はありません。

Mannyが指摘しているように、最初のスニペットはリリースされず、間違っています。

関連する問題