我正在转换旧的iPhone项目使用ARC。我提出了一个模态视图控制器,并在解雇它时获得EXC_BAD_ACCESS - 无法弄清楚原因,并且我怀疑我错过了ARC如何工作的基本原理。为什么使用ARC时此代码会导致EXC_BAD_ACCESS?
正在呈现的视图控制器是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,在代理中输入dismissCorrectionsController,返回cancelCorrection,并在取消修改的结束处返回EXC_BAD_ACCESS。
self.correctionsDelegate似乎指向在任何时候(检查它的变量视图的有效对象显示对象和值我希望,我也得到下面的控制台看起来没问题)。
(lldb) po self.correctionsDelegate
<SyncController: 0x17b9a970>
,真正让我困惑的部分:
1)堆栈跟踪显示EXC_BAD_ACCESS正在发生的事情里面objc_retain。 为什么?这里保留着什么?
2)0x44内存地址是指什么?
请执行以下操作。在'cancelCorrection'方法的下一行if(self.correctionsDelegate)'中设置一个断点。当你的应用程序在控制台'po self.correctionsDelegate'中击中断点类型时,让我知道输出是什么。 – LuisCien
更新了问题。据我可以告诉self.correctionsDelegate指向一个有效的对象,这是呈现视图控制器。 –
由于这似乎是内存损坏错误('objc_retain'),您可能需要启用僵尸对象。另外,让我指出'if(someObject)[someObject someMethod];'是多余的,因为'[nil someMethod];'是有效的Objective-C – Olotiar