ARC不会释放实例变量

时间:2012-04-26 14:55:17

标签: iphone objective-c ios memory-management automatic-ref-counting

我遇到ARC问题。经过几个小时的调试后,我放弃了,决定在这里查看。

基本上我有MainViewController,它会创建PreviewsView的实例。

PreviewsView我有委托和dataSource属性:

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

我在PreviewsView中创建MainViewController的实例,将self设置为delegatedataSource,将其添加到查看并保存为实例变量:< / p>

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

然后,当我从导航控制器中删除MainViewController时,ACR deallocates是,但是previewsView仍然存在(WHY ???)并且实际运行触发[self.delegate doSomeStuff]的方法。由于MainViewController已经解除分配 - 它会抛出 EXC_BAD_ACCESS

基本上是这样的:

  • MainViewController拥有PreviewsView(previewsView)
  • 实例的实例
  • MainViewController
  • delegate分配为dataSourcePreviewsView的实例
  • MainViewController的解除分配实例后,previewsView仍处于活动状态且正在运行。

任何想法为什么? 感谢。

2 个答案:

答案 0 :(得分:2)

在释放MainViewController之前,你需要将你的委托设置为nil     previewsView.delegate = nil;     previewsView.dataSource = nil;

在MainViewController的dealloc方法中优先调用此代码 - &gt;你仍然可以像这样使用ARC

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

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

答案 1 :(得分:1)

unsafe_unretained并不是一个伊娃。 __weak确实。

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

通常所有作为ivars保存的IBOutlets或子视图都应该是__weak。如果在将其添加为子视图后不需要previewsView,则可以删除ivar。

希望这有帮助!