古い iPhone プロジェクトを ARC を使用するように変換しています。モーダル ビュー コントローラーを提示していますが、それを閉じると EXC_BAD_ACCESS が発生します。理由がわかりません。また、ARC のしくみに関する基本的なことが欠けていると思われます。
提示されているView ControllerはCorrectionsControllerであり、デリゲートを使用して、提示しているView Controllerにそれを閉じるように知らせます。これらは、ヘッダー ファイルからの関連ビットです。
@protocol CorrectionsControllerDelegate
- dismissCorrectionsController;
@end
@property (nonatomic, weak) id<CorrectionsControllerDelegate> correctionsDelegate;
コントローラーは次のメソッドで初期化されます。
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil delegate:(id<CorrectionsControllerDelegate>)_delegate {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
self.correctionsDelegate = _delegate;
// do other init stuff
}
return self;
}
非表示ボタンは次のメソッドを呼び出します。
- (void)cancelCorrection {
if (self.correctionsDelegate)
[self.correctionsDelegate dismissCorrectionsController];
// EXC_BAD_ACCESS happens here
}
表示側のビュー コントローラーは、次のように CorrectionsController を初期化します。
// in .h file
@property (nonatomic, strong) CorrectionsController *corrections;
@property (nonatomic, strong) UINavigationController *secondNavigationController;
// in .m file
NSString *nibName = @"CorrectionsController";
self.corrections = [[CorrectionsController alloc] initWithNibName:nibName bundle:nil delegate:self];
self.secondNavigationController = [[UINavigationController alloc] initWithRootViewController:self.corrections];
if (isiPad()) {
self.secondNavigationController.modalPresentationStyle = UIModalPresentationFormSheet;
}
[self presentViewController:self.secondNavigationController animated:YES completion:nil];
また、CorrectionsControllerDelegate プロトコルを実装します。
- (void)dismissCorrectionsController {
[self dismissViewControllerAnimated:TRUE completion:nil];
}
さて、楽しい部分です。コードをステップ実行すると、実行は cancelCorrection に流れ、デリゲートに DismissCorrectionsController に入り、cancelCorrection に戻り、cancelCorrection の最後で EXC_BAD_ACCESS になります。
self.correctionsDelegate は常に有効なオブジェクトを指しているように見えます ([変数] ビューで調べると、期待するオブジェクトと値が表示され、コンソールで次のように表示されますが、問題ないようです)。
(lldb) po self.correctionsDelegate
<SyncController: 0x17b9a970>
私を本当に混乱させる部分:
1) スタック トレースは、 EXC_BAD_ACCESS が objc_retain 内で発生していることを示しています。 なんで? ここに保持されているものは何ですか?
2) 0x44 メモリ アドレスは何を参照していますか?