ふとしたきっかけでdeallocが呼ばれないUIViewControllerのサブクラスができてハマってしまいました。
小ネタですがメモしておきます。
[self.navigationController popViewControllerAnimated:YES];popViewControllerAnimated:の裏側では popされたViewControllerがreleaseされてdeallocが呼ばれるはずです。
ところが
下のような構成のViewContorllerではpopされてもdeallocメソッドが呼ばれませんでした。
UITableViewControllerを使わずに、素のUIViewControllerのUIViewにUITableViewを埋め込もうとしています。
UIViewControllerとTableViwe間でやりとりをするために、お互いに相手のpropertyを持たせています。
@interface MyTableView : UITableView
{
MyViewController *myViewController;
}
@property (nonatomic, retain) MyViewController *myViewController;
@end @interface MyViewController : UIViewController
{
MyTableView *myTableView;
}
@property (nonatomic, retain) MyTableView *myTableView;
@end
@implement MyViewController
@synthesize myTableView;
- (void)loadView {
[super loadView];
self.myTableView = [[MyTableView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
myTableView.myViewController = self;
[self.view addSubview:myTableView];
}
- (void)dealloc { // なぜかこれが呼ばれない
[myTableView release];
[super dealloc];
}
@end
どうもmyTableView.myViewController = self;このようにpropertyのpropertyにselfを指定してしまうとdeallocが呼ばれなくなるようです。対処法としてはselfを指定しているpropertyにnilをセットすること。
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidAppear:animated];
if (self.parentViewController == nil) { // popされた時のみ実行される
myTableView.myViewController = nil;
}
}delegateパターンでも同じようにnilをセットしてやる必要があるので注意です。
[2011/02/15 追記]
上のと似たような事例ですがまたdeallocが呼ばれない現象が発生したのでメモしておきます。
// NSArrayのプロパティにselfを格納する
self.dataSourceArray = [NSArray arrayWithObjects:self, obj1, obj2, nil];NSArrayに(NSDictionaryも)値を入れるとその時点でretainCountがひとつ増えます。なので上の事例と同じように、例えばviewDidDisappearなどで
dataSourceArray = nil;としてやる必要があります。




0 comments:
コメントを投稿