0

私のビューには 45 秒近くUIButtonあります。ボタンがメモリに割り当てられていないことはわかっています。何らかの理由でコンパイラがメモリを割り当て/解放しますが、このビューでデバイスが遅くなることに気付きました。UIButton??でメモリリークを避けるために

ボタンをビューに配置する方法は次のとおりです。

myView.h で:

UIButton *btn1;

myView.m で:

btn1 = [UIButton buttonWithType:UIButtonTypeCustom];
[btn1 setTitle:@"btn1" forState:UIControlStateNormal];
[btn1 addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
btn1.backgroundColor = [UIColor clearColor];
btn1.frame = CGRectMake(  arc4random() % 920, arc4random() %600+50  , 65, 65);
[self.view addSubview:btn1];

そしてそれを削除する方法:

for(UIButton* b in [self.view subviews]){
    [b removeFromSuperview];
    b = nil;

}
4

4 に答える 4

4

メモリ リーク自体がアプリの大幅な速度低下を引き起こすことはありません。それらの影響によりメモリがいっぱいになり、十分な数になると、メモリの過剰な使用によりオペレーティング システムがアプリを強制終了します。(オペレーティング システムがアプリを強制終了しなかった場合は、速度が低下する可能性がありますが、アプリが強制終了されるため、問題はありません)。

いずれにせよ、メモリ リークが心配な場合は、Instruments を起動して、ビューが表示されたときにメモリ リークが検出されるかどうかを確認できます。

おそらく、表示が遅い理由は、メモリに 45 個の画像をロードし、ディスクから読み取る必要があるためです (これは遅いです)。それらを事前にロードすることを考えて、これが改善されるかどうかを確認してください。

イメージをプリロードする簡単な方法は、次の方法でインスタンス化することimageNamedです。

 UIImage* img = [UIImage imageNamed:@"myButton1.png"];

すべてのボタンに対してそのメソッドを呼び出し、関連するすべての呼び出しを別のメソッドで収集することができます。たとえば、起動時やその他の必要なときに呼び出すことができます。

編集:

ビューに入って終了し、ビューに再び入るときなど

注意: スーパービューからボタンを削除する必要はありません (通常の状態では): これは、スーパービューを削除するときにフレームワークによって行われます。これがアプリの速度を低下させている可能性がありますか?

さらに、ビューを出入りするときに問題が発生した場合は、ビュー全体を「キャッシュ」してみてください(たとえば、一度だけインスタンス化し、必要なときに表示するなど)。

于 2012-10-18T11:18:33.993 に答える
0

私はこのように自動解放プールを使用しています。これにより、自動リリース内で作成されたものがさらに解放されます。パフォーマンスを向上させるために、この方法で多くのautoreleasepoolをテーブルに追加します

@autoreleasepool {
                    UIButton *btn=(UIButton*)[cell3.contentView.subviews objectAtIndex:btncont];

                    btn.tag=i;
                    [btn addTarget:self action:@selector(MozaicTblBtnSelection:) forControlEvents:UIControlEventTouchUpInside];

                    UIImage* img =  [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@/downloads/%@/files/%@.jpg",del.LocalPath,del.CompFolder,del.RepId,pi.STOCK_CODE]];

                    if(img!=nil)
                    {   
                        [btn setImage:img forState:UIControlStateNormal];

                        [btn.layer setBorderColor:[UIColor blackColor].CGColor];
                        [btn.layer setBorderWidth:1.0];

                    }
                    else
                    {
                        [btn setImage:[UIImage imageNamed:@"no_privew95x77.jpg"] forState:UIControlStateNormal];

                    }
                }
于 2012-10-18T11:25:46.953 に答える
0

これがあなたの助けになることを願っています...

    UIScrollView *scrlView =[[UIScrollView alloc]initWithFrame:self.view.frame];
    scrlView.tag=123;
    [scrlView  setBackgroundColor:[UIColor blueColor]];

    for(int i=0;i<45;i++)
    {
       UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeCustom];
        [btn1 setTitle:@"OK" forState:UIControlStateNormal];
        btn1.tag=i;
        [btn1 addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
        btn1.backgroundColor = [UIColor clearColor];
        btn1.frame = CGRectMake(  arc4random() % 300, arc4random() %420  , 30, 30);
        [scrlView addSubview:btn1];
    }
    [scrlView setContentSize:CGSizeMake(320, 460)];
    [self.view addSubview:scrlView];

&CickEventを取得する

    -(IBAction)btnClicked:(UIButton*)sender
    {
        NSLog(@"Button No :%d Clicked",sender.tag);
    }

&削除するためにできることは

    for(UIButton* b in [[self.view viewWithTag:123] subviews])
    {
        [b removeFromSuperview];
    }
于 2012-10-18T11:41:23.623 に答える
0

使用できます

@autoreleasepool {   //You UIButtons creation code goes here  }

これにより、autoreleasepool スコープ内で作成されたメモリが解放されます。cellForAtIndexPath メソッドに autoreleasepool を使用していますが、カスタム セルといくつかのデータベース クエリで 10000 行を超える場合があります。

于 2012-10-18T11:20:12.713 に答える