2011-08-13 12 views
1

私は私の.hファイルで私ののUIViewControllerこのように定義UIScrollViewのを持っている:私はことを読ん私の財産は潜在的なリークであり、どうすれば解決できますか?

@synthesize imageScrollView = _imageScrollView; 

#import <UIKit/UIKit.h> 

@interface TestViewController : UIViewController <UIScrollViewDelegate> 

@property (nonatomic, retain) UIScrollView * imageScrollView; 

@end 

はその後、私の.mファイルで、私は次のことを持っていますこれは自動的に私が通常は.hファイルに入力する_imageScrollViewを作成しますか? (UIScrollView * _imageScrollView)

私の.hファイルから重複したコードを削除するので、好きです。

Potential leak of an object allocated on line #linenumber 
:ビルドのXcodeは私にこれを言った後に今

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

[super dealloc]; 
} 

self.imageScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0 - 20.0 - 49.0)]; 
[_imageScrollView setDelegate:self]; 
[_imageScrollView setPagingEnabled:YES]; 
[_imageScrollView setBounces:NO]; 
[_imageScrollView setShowsHorizontalScrollIndicator:NO]; 
[_imageScrollView setShowsVerticalScrollIndicator:NO]; 
[_imageScrollView setContentSize:CGSizeMake(320.0 * 3.0, 480.0 - 20.0 - 49.0)]; 

そしてにdeallocリリースとはnilで:今私のloadViewメソッドに私が残りを行い

これは私がこれを変更すると消えます:

これに
self.imageScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0 - 20.0 - 49.0)]; 

self.imageScrollView = [[[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0 - 20.0 - 49.0)] autorelease]; 

なぜ私は私がのdeallocでそれを解放していたときにこれを自動解放する必要がありますか?私は間違って何をしていますか?

このメモリの警告は、あなたのimageScrollViewプロパティはretain財産であると宣言されているため

答えて

2

それはだ...ないユキヒョウと私のMacBookに、インストールライオンと私のiMac上でXcodeで発生します。つまり、アクセサを設定すると、アクセッサ(@synthesizeによって生成されます)は自動的に値を保持します。この動作を望まない場合は、プロパティをassignと宣言する必要があります。しかし、doはこの場合にこの動作が必要です。

とにかく、オブジェクトはコード内に2回、アクセサーによって1回保存されるため、決して解放されません。 self.imageScrollView =[self setImageScrollView:]とちょうど同じことを忘れないでください。

(エラーがないため、古いXcodeのは、エラーがない気付いていないのでそして最後に、メモリの警告はライオンに発生します。)

+0

ああ、それは今私には意味があります(私はここに入力することはできないようです)どうすれば自動解除を避けることができますか?それとも、この場合の唯一のオプションですか?通常、私は一時的なオブジェクトを作成するとき、私はそれを終了した直後にそれをリリースします。おそらく一度だけそれを保持する方法があるときに、このようなものでオートリリースプールを埋めることは悪いことではありませんか? –

+1

ここではオートレリーズが最適です。 autoreleaseプールが遅くなることは事実ですが、問題のコードが文字通り何千回も呼び出された場合に限ります。タイトなループでたくさんのものを割り当てていた場合は、新しいビューを指すように一時変数を作成し、それにimageScrollViewを設定して、temp変数でreleaseを呼び出すことができます。そうすることで、リリース前に設定できるので、自動解除する必要はありません。 (ただし、あなたが気づいていない場合にのみ) – andyvn22

+0

UIScrollView * imageScrollView = [[UIScrollView alloc] init]; [self setImageScrollView:imageScrollView]; [imageScrollView release];アプリは遅くない(または私はそれに気づいていない)が、将来のプロジェクトのために私はちょうどこれを明確にしたい(しかし、それは今だと思う、もう一度ありがとう!) –

2

あなたはretainオプションであなたの財産を定義しました。つまり、オブジェクトをそのプロパティに割り当てると、オブジェクトが保持されます。つまり、オブジェクトの所有権を取得します。この場合は、UIScrollViewを必要なときに使いこなしたいからです。 allocnewcopy、またはmutableCopyで始まる名前のメソッドから返されたオブジェクトも所有していることに注意してください。

だから、あなたのコードを見て、あなたはあなたがallocで作成UIScrollViewを所有していることを見ることができますが、プロパティにそれを格納するとき、あなたは再び所有権を主張。つまり、メモリは再利用されません。 autoreleaseを呼び出すと、プロパティに割り当てる前にオブジェクトの所有権が放棄されます。つまり、deallocreleaseを呼び出すことが意図したとおりに機能します。

Objective-Cプログラミング言語のドキュメントのMemory Management Programming GuideDeclared Propertiesのセクションを読むことをお勧めします。

+0

ありがとうございました答え:悲しいことに、2人に正しい答えを与えることは不可能です!私はもう一度読んでください:) –

+0

+1:いい参考資料! – andyvn22

関連する問題