在ARC模式下释放的对象

时间:2015-04-07 19:36:26

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

对象在ARC模式下被释放并导致崩溃。我的代码如下;

BlockAlertView* alert = [BlockAlertView alertWithTitle:title message:message];
[alert setCancelButtonWithTitle:NSLocalizedString(@"No", @"No Button") block:nil];
[alert addButtonWithTitle:NSLocalizedString(@"Yes", @"Yes Button") block:^{
        //Do Something
}];
[alert show];

它显示正确的警报视图(这是自定义UIView),但当我点击其中一个按钮时它会崩溃。

崩溃日志;

2015-04-07 22:28:17.065 Test[3213:781570] <BlockAlertView: 0x16bb4160> 2015-04-07 22:33:01.746 Test[3213:781570] *** -[BlockAlertView performSelector:withObject:withObject:]: message sent to deallocated instance 0x16bb4160

以下是BlockAlertView的源代码;

BlockAlertView on Github

现在我无法估计这方面的任何线索并让我老了。 任何意见都将非常感谢!

3 个答案:

答案 0 :(得分:1)

将您的alert对象分配到当前功能之外的某个位置。一个简单的可能性就是使它成为一个实例变量。如果这不实用,请创建一个您分配/ init的实例NSMutableArray *retainedItems;,并将其填入。

答案 1 :(得分:1)

看起来像是该项目的设计缺陷。该类命名为BlockAlertView,因为它实际上并不是UIView的子类。如果它是一个视图并且它被添加到视图层次结构中,那么视图层次结构将确保它在被查看时保持活动状态。因为视图保持活动状态,但是创建视图BlockAlertView的对象不被任何东西所控制,并且在调用操作时BlockAlertView已经很久了。

这将要求您保留strong ivar来引用此&#34;控制器&#34;对象,nil完成块中的ivar是明智的。

BlockAlertView *alertController = [BlockAlertView alertWithTitle:title message:message]; {
  [alertController setCancelButtonWithTitle:NSLocalizedString(@"No", @"No Button") block:nil];

  __weak __typeof(self) weakSelf = self;
  [alertController addButtonWithTitle:NSLocalizedString(@"Yes", @"Yes Button") block:^{
    //Do Something
    weakSelf.alertController = nil;
  }];

  [alertController show];
}

self.alertController = alertController;

答案 2 :(得分:1)

据推测,该代码在转换为ARC之前正常工作。

要解决此问题,您需要在self方法中创建对-show的强引用,并在-dismissWithClickedButtonIndex:animated:(您看到[self autorelease]中发布此引用注释掉。)

您可以使用一个简单的实例变量来执行此操作:

id _selfReference;

self分配到_selfReference中的-show

- (void)show
{
    _selfReference = self;
    ...

然后在您_selfReference注释掉的两个地方的-dismissWithClickedButtonIndex:animated:中将[self autorelease]设置为nil。