简体   繁体   English

在ARC模式下释放的对象

[英]Object deallocated in ARC mode

The object is deallocated in ARC mode and causes crash. 该对象在ARC模式下被释放并导致崩溃。 My code below; 我的代码如下;

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];

It appears the correct alert view(which is custom UIView) but when I click one of the button it crashes. 它看起来是正确的警报视图(这是自定义UIView),但是当我单击其中一个按钮时它会崩溃。

The crash log; 崩溃日志;

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

Here is the source code of BlockAlertView; 这是BlockAlertView的源代码;

BlockAlertView on Github Github上的BlockAlertView

For now I can't estimate any of the clues for this and makes me old. 现在我无法估计这方面的任何线索并让我老了。 Any input will be much appreciated! 任何输入将非常感谢!

Assign your alert object to live somewhere beyond your current function. alert对象分配到当前功能之外的某个位置。 One simple possibility is to just make it an instance variable. 一个简单的可能性就是使它成为一个实例变量。 If that's not practical, create an instance NSMutableArray *retainedItems; 如果这不实用,请创建一个实例NSMutableArray *retainedItems; which you allocate/init, and stuff this into. 你分配/ init,并将其填入。

Looks like a design flaw in that project. 看起来像是该项目中的设计缺陷。 The class is poorly named BlockAlertView as it's not actually a subclass of UIView . 这个类命名很差BlockAlertView因为它实际上并不是UIView的子类。 If it were a view and it was added to the view hierarchy then the view hierarchy would ensure it stayed alive whilst being viewed. 如果它是一个视图并且它被添加到视图层次结构中,那么视图层次结构将确保它在被查看时保持活动状态。 As it is the view is kept alive but the object that created the view BlockAlertView is not held onto by anything and by the time the actions are called BlockAlertView is long gone. 由于视图保持活动状态,但是创建视图BlockAlertView的对象并没有被任何东西保留,并且当动作被调用时, BlockAlertView早已不复存在。

This will require you to keep a strong ivar around to reference this "controller" object and it would be sensible to nil out that ivar in the completion blocks. 这就要求你保持一个strong伊娃身边引用这个“控制器”的对象,这将是明智的nil出在完成该块伊娃。

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;

Presumably, that code worked correctly before it was converted to ARC. 据推测,该代码在转换为ARC之前正常工作。

To fix it, you'll need to create a strong reference to self in the -show method, and release this reference in -dismissWithClickedButtonIndex:animated: (where you see [self autorelease] commented out). 要修复它,你需要在-show方法中创建一个强引用self ,并在-dismissWithClickedButtonIndex:animated:你看到[self autorelease]注释掉的地方)发布这个引用。

You can do this with a simple instance variable: 您可以使用简单的实例变量执行此操作:

id _selfReference;

Assign self to _selfReference in -show : -show _selfReference self指定给_selfReference

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

and then set _selfReference to nil in -dismissWithClickedButtonIndex:animated: in the two places where you see [self autorelease] commented out. 然后将_selfReference设置为nil in -dismissWithClickedButtonIndex:animated:在你看到[self autorelease]注释掉的两个地方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM