コメントで指摘を受け考え直した。
前回 assign と書いたが、これを改め retain にする。
見本
UIViewController でコントロールへの IBOutletを作成する時の見本
@property (nonatomic, retain) IBOutlet UITextField* textField;
あわせて viewDidUnload で開放する。
- (void)viewDidUnload { self.textField = nil; }
この2つはセットで使う。
理由
iPhoneの場合メモリ不足などが発生した場合、UIViewControllerが使用している UIView が開放される場合がある。前回の assign の場合、明示的に開放しなくても親ビューの開放と共にその上のコントロールも開放されるのでメモリリークの観点からは問題ない。しかし、UIViewの開放は意図しないタイミングで起こるために、誤って親ビューの解放後にコントロールへアクセスすることが起きうる。この場合、親ビューの開放に伴ってコントロールも開放されているので例外が出てクラッシュしてしまう(開放済みのオブジェクトへのアクセス)。また場合によっては親ビューの突然の開放があった場合でも入力中の文字列を退避したいケースがあるかもしれない。これらの理由により、コントロールのメモリ管理のオーナーシップを自分で持ってコントロールした方が良いと思われる。
参考
Xcodeが生成するテンプレートのコメントにも IBOutlet接続された subviewsの開放の件は書いてありますな。
- (void)viewDidUnload { // Release any retained subviews of the main view. // e.g. self.myOutlet = nil;
ドキュメントにも。
Memory Management Programming Guide: Memory Management of Nib Objects
Responses
Leave a Response