resignFirstResponder导致EXC_BAD_ACCESS

时间:2010-08-31 15:54:13

标签: iphone cocoa-touch uitextfield first-responder

我在UITableViewCell上有一个UITextField,在另一个单元格上有一个按钮。

我点击UITextField(出现键盘)。

UITextField具有以下方法:

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
        NSLog(@"yes, it's being called");
 owner.activeTextField = textField;
 return YES;
};

其中owner.activeTextField是(保留,非原子)属性。

问题 当键盘可见时,我将单元格滚出视图。 然后,我单击位于不同单元格上的按钮。按钮调用:

[owner.activeTextField resignFirstResponder]

这会导致EXC_BAD_ACCESS。

有什么想法吗?细胞绝对是在记忆中。我的猜测是,一旦它消失,它将从视图中删除,其中一个属性(父视图?)变为零,这会导致所述错误。

我是对的吗?

TL; DR;当从视图中删除UITextField时,如何删除键盘(重新签名第一响应者)?

3 个答案:

答案 0 :(得分:2)

有时候问题可能是另一个层次......检查并确保响应者链中的下一个对象(随后接收到的变为第一个响应消息的对象)不是垃圾。只是一个想法。

答案 1 :(得分:0)

您是否检查过owner.activeTextField以查看是否已取消分配/设置为nil?不确定是否会调用EXC_BAD_ACCESS,但值得一试。

你还有NSNotificationCenter的电话吗?我正在努力解决今天类似的问题导致EXC_BAD_ACCESS导致becomeFirstResponder,这是因为我在错误的委托上调用了[[NSNotificationCenter defaultCenter] removeObserver:keyboardObserver];

答案 2 :(得分:0)

有点老了,但由于我对传统的手动引用计数应用程序遇到了同样的问题,我会试一试。注意:这个问题不应该再发生在 ARC 上了(如果确实如此,我的解决方案肯定不适合那里......)。

似乎发生的事情是:

  • 文本字段保存到单元格中并且(可能已结束)保留
  • 当您使用文本字段滚动单元格时,单元格被循环使用(这很好),但文本字段不是(这就是为什么当错误发生时文本字段仍在内存中)
  • 此时,正确解雇键盘会使第一个响应者退出文本字段,但随着调用向下移动视图层次结构,它会再次访问不在内存中的单元格。

问题的一个简单(和imo优雅)解决方案将是

  1. 修复uitextfield的过度保留(如果有)
  2. 将UITextField子类化为在解除分配之前重新签署第一响应者状态
  3. 单一方法,如下:

    - (void) dealloc {
      [self resignFirstResponder];
      [super dealloc];
    }
    

    将是必需的,一旦单元格离开视图,这将具有移除键盘的副作用。

    另一个解决方案(我选择的解决方案,出于各种原因)将手动保留并使用文本字段回收单元格,直到表格被解除分配。

    我确定你已经解决了你的问题,但我希望这会帮助其他人...