0

私はメモリ管理を掘り下げていましたが、これを見つけました。

プロパティボタンを作成しました。

@property (nonatomic, retain) UIButton *button;

ViewdidLoad メソッドでは、次のコードを記述しました。

self.button = [[UIButton alloc] initwithFrame : CGRectMake(10, 10, 20, 20)];
[self.view addsubView:self.button];

XCode分析を行うと、33行目で割り当てられた変数の潜在的なリークが発生しています。セルフボタン。

なぜこれが起こるのですか?ローカル UIButton を作成し、それを self.button に割り当てて使用すると、潜在的なリークはありません。self.button または任意のプロパティ変数にメモリを割り当てると、リークします。

ありがとうジテン

4

5 に答える 5

2

self.button に値を割り当てると、合成された setter メソッドが呼び出されます。

- (void)setButton:(UIButton *)button;

プロパティ宣言に "retain" 属性を追加したため、合成されたセッターは、設定されたオブジェクトに対して "retain" を自動的に呼び出します。これにより、オブジェクトの保持カウントが増加します。

UIButton で「alloc」を呼び出すと、オブジェクトの保持カウントも増加します。

したがって、 self.button = [UIButton alloc] を実行すると、基本的に保持カウントが 2 増加します。そのため、リークの可能性があります。

これを修正するには、次のいずれかを実行します。

self.button = [[[UIButton alloc] initwithFrame : CGRectMake(10, 10, 20, 20)] autorelease];

また

UIButton *temp = [[UIButton alloc] initwithFrame : CGRectMake(10, 10, 20, 20)];
self.button = temp;
[temp release];

また

_button = [[UIButton alloc] initwithFrame : CGRectMake(10, 10, 20, 20)]; 
于 2013-04-11T04:49:35.120 に答える
2

@property (nonatomic, retain) UIButton *button;これを使用して、オブジェクトを保持しています。

今使用self.button = [[UIButton alloc] initwithFrame : CGRectMake(10, 10, 20, 20)];すると、メモリが割り当てられ、保持カウントが 1 増加します。

したがって、オブジェクトの保持カウントが増加するため、これはリークです。ローカルオブジェクトがあり、割り当ててから再度解放する場合。したがって、余分な保持カウントはなく、リークもありません。

アブスターク

ファクトリ メソッドを使用するか、alloc、new、retain、copy、mutableCopyを使用してオブジェクトを作成すると、オブジェクトの保持カウントが毎回 +1 になります。この場合、あなたはオブジェクトを所有しています。あなたはそれを解放する責任があります。そのため、オブジェクトの保持カウントが -1になるオブジェクトの使用が終了したら、オブジェクトを解放する必要があります。

編集

今、あなたはやっています

@property (nonatomic, assign) UIButton *button;
self.button = [[UIButton alloc] init];
[self.button release];

ここでは、作成したプロパティの変数で呼び出す self を使用してオブジェクトにアクセスしています。プロパティ オブジェクトに対して +1 の保持カウントを送信しているため、それ自体がゲッターとセッターを持つプロパティとして 2 になります。したがって、これを行う代わりに、このようにインスタンス変数を使用できます。

@property (nonatomic, assign) UIButton *button;
_button = [[UIButton alloc] init];
[_button release];
于 2013-04-11T04:49:52.837 に答える
1

ARC の前は、通常、retain変数に対して次のようにします。

UIButton* btn = [[UIButton alloc] initwithFrame : CGRectMake(10, 10, 20, 20)];
self.button = btn;    // property increases retain count because of its declaration as "retain"
[btn release];

ARC では、おそらく次のようにします。

@property (nonatomic, weak) UIButton* button;

self.button = [[UIButton alloc] initwithFrame : CGRectMake(10, 10, 20, 20)];
[self.view addsubView:self.button];

2 番目の例は、サブビューをビュー コンテナーに追加すると、それを含むビューが新しい子を保持するため、 (retainまたはを介し​​て) プロパティにボタンを保持させる必要がないことを示しています。strong

もちろん、いくつかの例外があります。場合によっては、ビュー (ボタン) をスーパービューから実際に削除したいが、後で追加し直すために解放したくない場合があります。

そのため、UI オブジェクトを保持することが有効な場合もあります。ただし、通常は必要ありません。

更新:ここでコメントしたいのは、この種の問題こそが Apple が人々に ARC の使用を望んでいる理由だということです。これは非常に基本的なメモリ管理シナリオであり、多くの新しい開発者を悩ませ続けています。現時点では、初心者の iOS 開発者が ARC を使用しない理由はほとんどありません。

于 2013-04-11T04:50:09.463 に答える
1

インスタンスUIButtonが 2 回保持されています。[UIButton alloc]は保持されたインスタンスを作成し、buttonプロパティは を介し​​て割り当てられたときにそれを保持していますself.button。MRC (Manual Reference Counting) コードでは、保持しているものはすべて解放する必要があります。

ボタンを作成するときは、次の操作を行います。

UIButton *button = [[[UIButton alloc] initWithFrame:...] autorelease];
self.button = button;

または、`UIButton' の優先クリエーター メソッドを使用します。

self.button [UIButton buttonWithType:UIButtonTypeCustom];
self.button.frame = CGRectMake(...);

また、プロパティに割り当てられたオブジェクトをクリーンアップするたびにボタンを放す必要があります。MRC の代わりに ARC (Automatic Reference Counting) を使用すると、コーディングがはるかに簡単になります。

于 2013-04-11T04:51:52.370 に答える
0

あなたがそれを解放したかどうかはわかりませんが、メモリを割り当てるたびに解放する必要があります (プロジェクトで ARC が使用されていない場合)。したがって、次のように dealloc で解放するだけです。

-(void)dealloc {
    [button release];
    [super dealloc];
}
于 2013-04-11T04:54:41.323 に答える