应用程序崩溃,因为方法正在被释放

Posted

技术标签:

【中文标题】应用程序崩溃,因为方法正在被释放【英文标题】:App is crashing because a method is being deallocated 【发布时间】:2014-09-16 21:05:43 【问题描述】:

我有这段代码在 UIPopover 中创建 40 个 UITextField;当我尝试在其中一个文本字段中输入一个数字时,应用程序会因此崩溃:

-[ImportTABDelimitedFile respondsToSelector:]:消息发送到释放的实例

这是创建文本字段的代码:

//  create the uitextfields for user to match against their input file columns
CGRect nbrFieldRect = CGRectMake(x-20, y, 26.0f, 26.0f);
UITextField *nbrTextField = [[UITextField alloc] initWithFrame:nbrFieldRect];
if(colorYES)
    nbrTextField.backgroundColor = UIColorFromRGB(0xFFF9AF);
else
    nbrTextField.backgroundColor = [UIColor whiteColor];

nbrTextField.enabled = YES;
[nbrTextField setKeyboardType:UIKeyboardTypeNumberPad];
nbrTextField.textColor = [UIColor blackColor];
nbrTextField.tag = tagNumber + 100;  //  range: 170-215
nbrTextField.font = [UIFont systemFontOfSize:12.0f];
nbrTextField.borderStyle = UITextBorderStyleRoundedRect;
nbrTextField.returnKeyType = UIReturnKeyNext;
nbrTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
[nbrTextField addTarget:self action:@selector(mapUserFields) forControlEvents: UIControlEventEditingDidEnd];
nbrTextField.delegate = self;
[theView addSubview:nbrTextField];

这是 mapUserFields 的代码:

-(void)mapUserFields  

    NSLog(@"mapUserFields: textFieldDidEndEditing");

UPDATE #2 我运行了 Instruments,它显示 方法 正在被释放,这导致了崩溃;这是仪器输出的图像:

现在,问题是:为什么方法会被释放,我该如何解决?

【问题讨论】:

空 textField.delegate 不会导致崩溃。您的问题在其他地方。 是什么让你认为这是委托的错?我感觉释放的 40 个 uitextfields 对象与此有关。 @meda:它们被添加到视图中,因为它们没有被释放。至少不是我们在这里看到的代码。 【参考方案1】:

在创建文本字段并设置其其他属性时添加委托,如下所示:

UITextField *nbrTextField = [[UITextField alloc] initWithFrame:nbrFieldRect];
nbrTextField.delegate = self;

并实现它的委托方法,当你从键盘按下回车键时调用它:

- (BOOL)textFieldShouldReturn:(UITextField *)textField 
    [textField resignFirstResponder];
    return YES;

到目前为止,您发布的上述代码看起来还不错,直到您发布崩溃日志。

编辑:您发布的崩溃日志表明正在释放作为 UIControlEventEditingDidEnd 文本字段事件观察者添加的对象(在本例中为 ImportTABDelimitedFile)。

您能否通过创建具有保留类型的属性以及当您将属性集nil 关闭到 popover 变量来确保您在呈现类中保留弹出框的一件事。比如这样:

@property (nonatomic, retain) UIPopoverController *popoverController;

并且不要忘记在呈现弹出框时初始化和分配此属性。像这样将其委托设置为 self:

popoverController.delegate = self;

不要忘记实现委托,并在委托方法中,像这样清除属性变量:

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
    self.popoverController = nil; //if you are using non-arc, release it.

【讨论】:

发送什么选择器? @spokane-dude 根据您提供的崩溃日志查看我编辑的答案。【参考方案2】:

我发现了问题(在 Michael Dautermann 的帮助下)...我必须将被调用的方法设为如下属性:

iTABFile = [[ImportTABDelimitedFile alloc]init];

现在,它还没有发布,并且像冠军一样工作!谢谢大家的帮助;对此,我真的非常感激。标清

【讨论】:

【参考方案3】:

我猜测这里没有看到其余代码,但您需要做两件事。首先,设置创建所有文本字段的类以符合 UITextFieldDelegate 协议。我假设您粘贴上面代码的类就是那个类。

这是在头文件(.h)中完成的

同样,在创建 40 多个文本字段时,设置:

nbrTextField.delegate = self;

将让当前类充当 UITextFields 的委托。

希望对你有帮助

【讨论】:

以上是关于应用程序崩溃,因为方法正在被释放的主要内容,如果未能解决你的问题,请参考以下文章

iPhone:自定义自动释放池中的崩溃

释放自动释放对象不会使我的应用程序崩溃,为啥?

在执行功能时单击导航控制器上的后退按钮时应用程序崩溃

在flutter中释放apk安卓程序在启动时崩溃

应用程序崩溃后相机未释放

在自定义单元类应用程序中释放对象时崩溃