0

我对 ARC 有疑问。经过几个小时的调试,我放弃了,决定在这里检查。

基本上我有一个MainViewController,它创建的实例PreviewsView

PreviewsView我有委托和数据源属性:

@property (nonatomic, unsafe_unretained) IBOutlet id<PreviewsDataSource> dataSource;
@property (nonatomic, unsafe_unretained) IBOutlet id<PreviewsDelegate> delegate;

我创建PreviewsViewin 的实例MainViewController,设置selfdelegateand dataSource,将其添加到视图并保存为实例变量:

- (void)addPreviews {
    previewsView = [[PreviewsView alloc] initWithFrame:CGRectMake(0, 75, 1024, 480)];
    previewsView.dataSource = self;
    previewsView.delegate = self;
    [self.view addSubview:previewsView];
}

然后当我MainViewController从导航控制器中删除 ACR deallocates 时,BUTpreviewsView仍然存在(为什么???)并实际运行触发的方法[self.delegate doSomeStuff]。正如MainViewController已经解除分配 - 它抛出EXC_BAD_ACCESS

所以基本上:

  • 实例MainViewController拥有PreviewsView(previewsView)的实例
  • MainViewController分配为delegatedataSource在中的实例PreviewsView
  • 释放实例后MainViewController, previewsView 仍然存在并正在运行。

任何想法为什么?谢谢。

4

2 回答 2

2

在像这样 previewsView.delegate = nil; 释放 MainViewController 之前,您需要将您的代表设置为 nil;previewsView.dataSource = nil;

最好在您的 MainViewController 的 dealloc 方法中调用此代码->您仍然可以像这样与 ARC 一起使用它

- (void) dealloc
{
    previewsView.dataSource = nil;
    previewsView.delegate = nil;
    [super dealloc];
}

你应该记住协议!假设!您的 previewsView 实例仍然“活着”(通知的工作方式相同)并尝试向您的实例发送消息,无论它是死的还是活着的。因此,当 MainViewController 被释放时, previewsView 也是,但代表仍然“活着”。因此,您需要通过将它们设置为 nil 来取消对它们的授权;)

于 2012-04-26T16:45:26.967 回答
1

unsafe_unretained 不为零 ivar。__weak 确实如此。

MainViewController 成员是否previewsView保留它?在 viewDidUnload 或完成 previewsView 后,将其设置为 nil,即:previewsView = nil

一般来说,所有作为 ivars 的 IBOutlets 或子视图都应该是 __weak。如果您在将 previewsView 添加为子视图后不需要它,则可以删除 ivar。

希望这可以帮助!

于 2012-04-26T15:02:56.847 回答