UIKit コントロールの View構成と retainCount

2010年6月27日日曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

Nib利用時のメモリ管理について調査中。

こんなビューを作り、View構成とそれぞれのViewの retainCountを出してみた。

"display RetainCount" を押した時の処理(UIViewController内)
- (void)displayRetainCountOfView:(UIView*)view level:(int)level
{
 NSMutableString* indent = [NSMutableString string];
 for (int i=0; i < level; i++) {
  [indent appendString:@"  "];
 }

 for (UIView* subview in [view subviews]) {
  NSLog(@"%@[%@ retainCount]: %d", indent,
     [subview class], [subview retainCount]);
  if ([[subview subviews] count] > 0) {
   [self displayRetainCountOfView:subview level:level+1];
  }
 }
}

-(IBAction)display:(id)sender
{
 NSLog(@"[self.view  retainCount]: %d", [self.view retainCount]);
 [self displayRetainCountOfView:self.view level:0];
 
}

再帰的に回してサブビューも含めて表示している。

結果はこう。
[self.view  retainCount]: 4
[UILabel retainCount]: 2
[UIRoundedRectButton retainCount]: 7
  [UIButtonLabel retainCount]: 3
[UISwitch retainCount]: 2
  [_UISwitchSlider retainCount]: 3
    [UIImageView retainCount]: 3
    [UIImageView retainCount]: 3
    [UIView retainCount]: 3
      [UILabel retainCount]: 3
      [UILabel retainCount]: 3
    [UIImageView retainCount]: 3
[UISlider retainCount]: 2
  [UIImageView retainCount]: 3
  [UIImageView retainCount]: 3
  [UIImageView retainCount]: 3
[UIProgressView retainCount]: 2
[UITableView retainCount]: 2
  [UIImageView retainCount]: 3
  [_UITableViewSeparatorView retainCount]: 3
  [_UITableViewSeparatorView retainCount]: 3
  [_UITableViewSeparatorView retainCount]: 3
  [UIImageView retainCount]: 3
[UISegmentedControl retainCount]: 2
  [UISegment retainCount]: 3
    [UISegmentLabel retainCount]: 3
    [UIImageView retainCount]: 2
  [UISegment retainCount]: 3
    [UISegmentLabel retainCount]: 3
    [UIImageView retainCount]: 2
[UIRoundedRectButton retainCount]: 2
  [UIButtonLabel retainCount]: 3
[UITextField retainCount]: 2
  [UITextFieldRoundedRectBackgroundView retainCount]: 3
    [UIImageView retainCount]: 3
    [UIImageView retainCount]: 3
    [UIImageView retainCount]: 3
    [UIImageView retainCount]: 3
    [UIImageView retainCount]: 3
    [UIImageView retainCount]: 3
    [UIImageView retainCount]: 3
    [UIImageView retainCount]: 3
    [UIImageView retainCount]: 3
    [UIImageView retainCount]: 3
    [UIImageView retainCount]: 3
    [UIImageView retainCount]: 3
[UIImageView retainCount]: 2

メインのビューに配置したコントロールの retainCount は 2となっている(一つはsuperviewによるもので、もう一つは不明)。
"diplay retainCount" ボタンのみ retainCountが 7となっているのがわかる。action-targetで接続するとその管理下におかれ、増えているのだと思われる。
[UIRoundedRectButton retainCount]: 7

- - - -

基本的に UIViewController.view 上に配置されたコントロールは、その UIViewController が破棄された時に UIViewController.view が release され、芋づる式にすべて開放(release)される。この為、これらのコントロールを UIViewController 内で使う場合、メモリのオーナーシップは考えなくて良いはず。
(例) @propety (nonatomic, assign) IBOutlet UILabel* label;

逆に reatain してしまった場合、その UIViewController がメモリ解放の責任の一旦を担わなければならない。
(例) @propety (nonatomic, retain) IBOutlet UILabel* label;

開放のタイミングは dealloc 以外に、UIViewController の場合はその生存期間と viewのそれとが異なるのでそれを考慮する必要がある。具体的にはメモリ不足が発生すると didReceiveMemoryWarning が呼ばれ、そのタイミングで viewが開放される。retainしている場合はこの時に開放しないと UIViewControllerのOultet参照が残ったままになってしまう。
(ただ、その後 viewの再生成で再び Outletが再設定されるので、その時に古い参照が開放される。なので viewの破棄・再作成毎に発生するメモリリークは起こっても限定的?)

。。。この辺りを現在検証中。

Responses

Leave a Response

人気の投稿(過去 30日間)