Friday, February 24, 2012

UIView removeFromSuperview で subviews を解放

UIView removeFromSuperview で subviews を解放する際、以下のコードでは問題があります。

UIView *mainView = [[UIView alloc] init];

UIView *firstView = [[UIView alloc] init];
[mainView addSubview:firstView];
[firstView release];

UIView *secondView = [[UIView alloc] init];
[mainView addSubview:secondView];
[secondView release];

int c = [[mainView subviews] count];
for (int i = 0; i < c; i++) {
    [[mainView.subviews objectAtIndex:i] removeFromSuperview];
}

デバッグコンソールを確認すると、objectAtIndex:1 でエラーが発生しています。

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSMutableArray objectAtIndex:]: index 1 beyond bounds [0 .. 0]'

removeFromSuperview により subviews は更新され、mainView.subviews のカウントは減っていきます。このため [mainView.subviews objectAtIndex:i] してもすでにメモリにはないということになります。

[mainView.subviews objectAtIndex:0] にすればよいのですが、以下のようなコードでも解決します。

for (UIView *subview in [mainView subviews]) {
    [subview removeFromSuperview];
}