1

2つのボタンを持つ UINavigationBar をプログラムで設定しました。

-(void)setUpNavigationBar{
  //The Navbar
  UIImage *backgroundImage = [UIImage imageNamed:@"top_bar_gradient"];
  UINavigationBar *naviBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, MAINBAR_WIDTH, MAINBAR_HEIGHT)];
  [naviBar setTintColor:[UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0]];
  [naviBar setBackgroundImage:backgroundImage forBarMetrics:UIBarMetricsDefault];

  //Right Button
  UIButton *rButton = [UIButton buttonWithType:UIButtonTypeCustom];
  UIImage *rButImage = [UIImage imageNamed:@"top_icon_menu2"];
  [rButton setBackgroundImage:rButImage forState:UIControlStateNormal];
  [rButton addTarget: self.viewDeckController action:@selector(toggleRightView) forControlEvents:UIControlEventTouchUpInside];
  [rButton setFrame:CGRectMake(MAINBAR_BUTTON_X, MAINBAR_BUTTON_Y, MAINBAR_BUTTON_WIDTH, MAINBAR_BUTTON_HEIGHT)];
  UIBarButtonItem *rightButton = [[UIBarButtonItem alloc]initWithCustomView:rButton];

  //Left Button
  UIButton *lButton = [UIButton buttonWithType:UIButtonTypeCustom];
  UIImage *lButImage = [UIImage imageNamed:@"top_icon_menu1"];
  [lButton setBackgroundImage:lButImage forState:UIControlStateNormal];
  [lButton addTarget: self.viewDeckController action:@selector(toggleLeftView) forControlEvents:UIControlEventTouchUpInside];
  [lButton setFrame:CGRectMake(MAINBAR_BUTTON_X, MAINBAR_BUTTON_Y, MAINBAR_BUTTON_WIDTH, MAINBAR_BUTTON_HEIGHT)];
  UIBarButtonItem *leftButton = [[UIBarButtonItem alloc]initWithCustomView:lButton];

  //Put it all together
  naviBarItem.leftBarButtonItem = leftButton;
  naviBarItem.rightBarButtonItem = rightButton;
  naviBar.items = [NSArray arrayWithObjects:naviBarItem,nil];

  self.navigationItem.leftBarButtonItem = leftButton;

  [self.view addSubview:naviBar];

  // This was my approach preventing the heap growth.
  rightButton = nil;
  leftButton = nil;
}

- (void)viewDidLoad
{
  [super viewDidLoad];
  [self setUpNavigationBar];
}

インストゥルメントを介してアプリをプロファイリングし、XCode 5 でヒープショット (「ジェネレーション」と呼ばれます) を取得します。最初に自分のオブジェクトの問題を解決し、他のヒープ成長の問題が自分のオブジェクトから「カスケード」することを願っています。

したがって、アプリを閉じて開くたびに、UIBarButtonItem がヒープを 448 バイトずつ増やしていることがわかります (これは、ヒープショットを取得した後のルーチンです)。オブジェクトが 4 つ生きているため、オブジェクトが解放されないようです。ARC

問題は、アプリを閉じて開くたびにヒープが約 200 kb 増加していることです。メモリリークは次のとおりです。

銘柄の割り当て

さらに深く掘り下げると、関数の UIBarButtonItem であることがわかりsetUpNavigationBarます。

ここに画像の説明を入力

私の質問は、ここでメモリリークを防ぐ方法ですか? ARC が有効になっているため、オブジェクトを自分で解放することはできません。

4

1 に答える 1

2

あなたが犯している間違いは、入力するたびに新しいナビゲーション バーを作成していることですsetUpNavigationBar。ナビゲーション バーを作成し、それをサブビューとして追加します。つまり、ナビゲーション バーは保持され、ナビゲーション バーへの参照が失われるため、削除して解放することはできません。

からのみ呼び出すため、そのメソッドが複数回呼び出される理由はわかりませんが、viewDidLoadメモリ不足を奇妙に処理している可能性があります。

ナビゲーション バーをプロパティとして保存する必要があります。クラスのインターフェースでこれを使用します:

@property (nonatomic, strong) UINavigationBar *naviBar;

そして、コードを次のように変更します。

-(void)setUpNavigationBar{
    if (!self.naviBar)
    {
        //The Navbar
        UIImage *backgroundImage = [UIImage imageNamed:@"top_bar_gradient"];
        UINavigationBar *naviBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, MAINBAR_WIDTH, MAINBAR_HEIGHT)];
        self.naviBar = naviBar;
        [naviBar setTintColor:[UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0]];
        [naviBar setBackgroundImage:backgroundImage forBarMetrics:UIBarMetricsDefault];

        //Right Button
        UIButton *rButton = [UIButton buttonWithType:UIButtonTypeCustom];
        UIImage *rButImage = [UIImage imageNamed:@"top_icon_menu2"];
        [rButton setBackgroundImage:rButImage forState:UIControlStateNormal];
        [rButton addTarget: self.viewDeckController action:@selector(toggleRightView) forControlEvents:UIControlEventTouchUpInside];
        [rButton setFrame:CGRectMake(MAINBAR_BUTTON_X, MAINBAR_BUTTON_Y, MAINBAR_BUTTON_WIDTH, MAINBAR_BUTTON_HEIGHT)];
        UIBarButtonItem *rightButton = [[UIBarButtonItem alloc]initWithCustomView:rButton];

        //Left Button
        UIButton *lButton = [UIButton buttonWithType:UIButtonTypeCustom];
        UIImage *lButImage = [UIImage imageNamed:@"top_icon_menu1"];
        [lButton setBackgroundImage:lButImage forState:UIControlStateNormal];
        [lButton addTarget: self.viewDeckController action:@selector(toggleLeftView) forControlEvents:UIControlEventTouchUpInside];
        [lButton setFrame:CGRectMake(MAINBAR_BUTTON_X, MAINBAR_BUTTON_Y, MAINBAR_BUTTON_WIDTH, MAINBAR_BUTTON_HEIGHT)];
        UIBarButtonItem *leftButton = [[UIBarButtonItem alloc]initWithCustomView:lButton];

        //Put it all together
        naviBarItem.leftBarButtonItem = leftButton;
        naviBarItem.rightBarButtonItem = rightButton;
        naviBar.items = [NSArray arrayWithObjects:naviBarItem,nil];

        self.navigationItem.leftBarButtonItem = leftButton;

        [self.view addSubview:naviBar];
    }
}
于 2013-11-15T10:35:25.700 に答える