resignFirstResponder 导致 EXC_BAD_ACCESS

发布于 2024-09-16 21:25:12 字数 683 浏览 8 评论 0原文

我在 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 从视图中删除时,如何删除键盘(退出第一响应者)?

I've got a UITextField on UITableViewCell, and a button on another cell.

I click on UITextField (keyboard appears).

UITextField has the following method called:

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

Where owner.activeTextField is a (retain, nonatomic) property.

The problem
When the keyboard is visible I scroll the cell out of the view.
I then click a button that is on a different cell. The button calls:

[owner.activeTextField resignFirstResponder]

And that causes EXC_BAD_ACCESS.

Any idea? The cell is most definitely in the memory. My guess is that once it disappears it is removed from the view and one of it's properties (parent view?) becomes nil and that causes the said error..

Am I right?

TL;DR; How can I remove the keyboard (resign first responder) when UITextField is removed from the view?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

仙女山的月亮 2024-09-23 21:25:13

有时问题可能会更严重......检查并确保响应者链中的下一个对象(随后接收成为FirstResponder消息的对象)不是垃圾。只是一个想法。

Sometimes the problem can be another level deep... Check and make sure that the next object in the responder chain (the one that's subsequently receiving the becomeFirstResponder message) isn't garbage. Just a thought.

许仙没带伞 2024-09-23 21:25:13

您是否检查过 owner.activeTextField 以查看它是否已被释放/设置为 nil?不确定这是否会调用 EXC_BAD_ACCESS 但值得一试。

另外,您是否有对 NSNotificationCenter 的调用?我今天遇到了类似的问题,导致 becomeFirstResponder 上出现 EXC_BAD_ACCESS,这是由于我调用 [[NSNotificationCenter defaultCenter] removeObserver:keyboardObserver]; 位于不正确的委托上。

Have you checked owner.activeTextField to see if it has been deallocated / set to nil? Not sure if that would call a EXC_BAD_ACCESS but worth a try.

Also do you have any calls to NSNotificationCenter? I was struggling with something similar today which was causing an EXC_BAD_ACCESS on becomeFirstResponder, which was due to me calling [[NSNotificationCenter defaultCenter] removeObserver:keyboardObserver]; on the incorrect delegate.

逆蝶 2024-09-23 21:25:13

有点旧,但由于我刚刚使用旧的手动引用计数应用程序遇到了同样的问题,所以我会尝试一下。注意:ARC 不应该再出现这个问题(如果确实如此,我的解决方案绝对不适合那里......)。

似乎发生的情况是:

  • 文本字段被保存到单元格中,并且
  • 当您使用文本字段滚动单元格时(可能过度)保留,单元格被回收(这很好),但文本字段却没有(这就是为什么当错误发生时,文本字段仍然在内存中)
  • 此时,关闭键盘正确地放弃了文本字段的第一响应者,但是当调用沿着视图层次结构向下移动时,它击中了不再在内存中的单元格。

该问题的一个简单(并且在我看来优雅)的解决方案是

  1. 修复 uitextfield 的过度保留,如果任何子
  2. 之前放弃第一响应者状态

类 UITextField 在被释放单个方法

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

,就像这样:将是必需的,这将产生副作用一旦单元离开视野就可以移除键盘的好处。

另一种解决方案(这是我出于各种原因选择的解决方案)是手动保留并回收带有文本字段的单元格,直到表被释放。

我确信您已经解决了您的问题,但我希望这对其他人有帮助......

A bit old, but since I just had the same problem with a legacy manual reference counting app, I'll give it a try. Note: this problem shouldn't happen with ARC anymore (and if it does, my solution most definitely doesn't fit there...).

What seems to happen is that:

  • the textfield is saved into the cell and is (possibly over)retained
  • when you scroll the cell with the textfield, the cell get's recycled (which is good), but the textfield is not (which is why the textfield is still in memory when the bug happens)
  • at that point, dismissing the keyboard correctly resign the first responder for the textfield, but as the call travels down the view hierarchy, it hits the cell, which is not in memory anymore.

a simple (and imo elegant) solution for the problem would be to

  1. fix the over retention of uitextfield if any
  2. subclass UITextField to resign first responder status before being deallocated

a single method,like this:

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

would be required, which will have the side-effect benefit of removing the keyboard as soon as the cell gets out of view.

Another solution (which is the one I chose, for various reasons) would be to manually retain and recycle the cell with the textfield until the table is deallocated.

i'm sure you already solved your problem, but I hope this will help someone else...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文