我遇到ARC问题。经过几个小时的调试后,我放弃了,决定在这里查看。
基本上我有MainViewController
,它会创建PreviewsView
的实例。
在PreviewsView
我有委托和dataSource属性:
@property (nonatomic, unsafe_unretained) IBOutlet id<PreviewsDataSource> dataSource;
@property (nonatomic, unsafe_unretained) IBOutlet id<PreviewsDelegate> delegate;
我在PreviewsView
中创建MainViewController
的实例,将self
设置为delegate
和dataSource
,将其添加到查看并保存为实例变量:< / 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
分配为dataSource
和PreviewsView
的实例
MainViewController
的解除分配实例后,previewsView仍处于活动状态且正在运行。任何想法为什么? 感谢。
答案 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。
希望这有帮助!