我正在将一个旧的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,在委托中输入dismissCorrectionsController,返回cancelCorrection,并在cancelCorrection的处返回EXC_BAD_ACCESS。



self.correctionsDelegate似乎一直指向一个有效的对象(在“变量”视图中对其进行检查将显示我期望的对象和值,并且在控制台中可以看到以下内容)。
(lldb) po self.correctionsDelegate
<SyncController: 0x17b9a970>

真正使我困惑的部分:

1)堆栈跟踪显示EXC_BAD_ACCESS正在 objc_retain 内部发生。 为什么? 这里保留了什么?

2)0x44存储器地址指的是什么?

最佳答案

到目前为止,我能找到的最好的解释是模态控制器(CorrectionsController)似乎已在dismissCorrectionsController中立即释放,并且当执行返回cancelCorrection时不再有效。此更改似乎可以解决崩溃问题:

- (void)cancelCorrection {
    [self.correctionsDelegate performSelector:@selector(dismissCorrectionsController) ];
}

我会将这个答案标记为已接受,但对我来说仍然没有完全意义,因此,如果有人对正在发生的事情有了更好的解释,我会很乐意接受该答案。

07-24 15:33