在 ARC 模式下释放对象
Object deallocated in ARC mode
对象在 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的源代码;
现在我无法估计这方面的任何线索,让我老了。
任何输入将不胜感激!
将您的 alert
对象分配到您当前功能之外的某个地方。一种简单的可能性是将其设为实例变量。如果那不切实际,请创建一个您 allocate/init 的实例 NSMutableArray *retainedItems;
,然后将其填充到其中。
看起来像是该项目中的设计缺陷。 class 命名不当 BlockAlertView
因为它实际上不是 UIView
的子 class。如果它是一个视图并且它被添加到视图层次结构中,那么视图层次结构将确保它在被查看时保持活动状态。因为它是视图保持活动状态,但是创建视图 BlockAlertView
的对象没有被任何东西保留,并且在调用操作时 BlockAlertView
早已不复存在。
这将要求您保留一个 strong
ivar 来引用此 "controller" 对象,并且 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;
据推测,该代码在转换为 ARC 之前可以正常工作。
要修复它,您需要在 -show
方法中创建对 self
的强引用,并在 -dismissWithClickedButtonIndex:animated:
中释放此引用(您看到 [self autorelease]
注释掉了)。
您可以使用一个简单的实例变量来做到这一点:
id _selfReference;
在-show
中将self
分配给_selfReference
:
- (void)show
{
_selfReference = self;
...
然后在 -dismissWithClickedButtonIndex:animated:
中看到 [self autorelease]
被注释掉的两个地方 _selfReference
设置为 nil
对象在 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的源代码;
现在我无法估计这方面的任何线索,让我老了。 任何输入将不胜感激!
将您的 alert
对象分配到您当前功能之外的某个地方。一种简单的可能性是将其设为实例变量。如果那不切实际,请创建一个您 allocate/init 的实例 NSMutableArray *retainedItems;
,然后将其填充到其中。
看起来像是该项目中的设计缺陷。 class 命名不当 BlockAlertView
因为它实际上不是 UIView
的子 class。如果它是一个视图并且它被添加到视图层次结构中,那么视图层次结构将确保它在被查看时保持活动状态。因为它是视图保持活动状态,但是创建视图 BlockAlertView
的对象没有被任何东西保留,并且在调用操作时 BlockAlertView
早已不复存在。
这将要求您保留一个 strong
ivar 来引用此 "controller" 对象,并且 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;
据推测,该代码在转换为 ARC 之前可以正常工作。
要修复它,您需要在 -show
方法中创建对 self
的强引用,并在 -dismissWithClickedButtonIndex:animated:
中释放此引用(您看到 [self autorelease]
注释掉了)。
您可以使用一个简单的实例变量来做到这一点:
id _selfReference;
在-show
中将self
分配给_selfReference
:
- (void)show
{
_selfReference = self;
...
然后在 -dismissWithClickedButtonIndex:animated:
中看到 [self autorelease]
被注释掉的两个地方 _selfReference
设置为 nil