ARCへ移植の際に嵌ったこと
これまでARC非対応で作成していたソースを、ARC対応プロジェクトへの移植を行った。
その際、
・ライブラリソースなど、特定のファイルにはARCを対応させない
・Xcode上で、「Edit→Refactor→Convert To Objective-C ARC」で指摘された箇所を修正する
という対応を入れれば問題ないかなと思っていたのだが(上記2点については多くのサイトで掲載されている)、下記のようなところでエラーに嵌ってしまった。。
あるMainViewController.mにて
- (void)viewDidLoad
{
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
TestViewController *test = [[TestViewControlleralloc] initWithNibName:@"TestViewController"bundle:nil];
[self.view addSubview:test.view];
}
と、xibつきで作成したTestViewControllerを上記のようにaddSubviewする。
このTestViewControllerにはボタンがあって、そのボタンをタップしたときにEXC_BAD_ACCESSが発生してしまう。
対応として、以下のようにtestオブジェクトをインスタンス変数でもつようにすれば問題なく動作するようになった。
MainViewController.h
@interface ViewController : UIViewController
{
TestViewController *test;
}
EXC_BAD_ACCESSが発生した理由はおそらくだが、『エキスパート Objective-C プログラミング』の説明を読む限り、
TestViewController *test = [[TestViewControlleralloc] initWithNibName:@"TestViewController"bundle:nil];
には、実際のところは__strong修飾子がついていて、__strong修飾子のついた変数はその変数が含まれる変数スコープを抜けるときに、代入されたオブジェクトを解放するから。
ただ、動的にxibつきのファイルのviewをaddしたいなんてこともあるだろうから、すべてをインスタンス変数としてもつのは難しいだろうし、なにかいい方法があるはずだが、、、まだわからない。
(インスタンス変数に配列をつくって、その配列がtestオブジェクトを参照するようにしたところエラーは発生しないので、そんな方法もありかなぁ。汚いすぎるけど)