我正在将旧 iPhone 项目转换为使用 ARC。我正在展示一个模态视图控制器,并在关闭它时得到 EXC_BAD_ACCESS - 不知道为什么,我怀疑我错过了关于 ARC 工作原理的一些基本知识。
呈现的视图控制器是 CorrectionsController,它使用委托来让呈现的视图控制器知道将其关闭。这些是头文件中的相关位:
@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,在delegate中进入dismissCorrectionsController,返回cancelCorrection,在cancelCorrection结束时执行EXC_BAD_ACCESS。
self.correctionsDelegate 似乎始终指向一个有效对象(在“变量”视图中检查它会显示我期望的对象和值,并且我在控制台中得到以下看起来不错的内容)。
(lldb) po self.correctionsDelegate
<SyncController: 0x17b9a970>
真正让我困惑的部分:
1) 堆栈跟踪显示 EXC_BAD_ACCESS 发生在objc_retain内。 为什么? 这里保留了什么?
2)0x44内存地址指的是什么?