【问题标题】:Crash when using gesture recognizers in StoryBoard在 StoryBoard 中使用手势识别器时崩溃
【发布时间】:2012-02-20 14:12:00
【问题描述】:

更新

对于旧版本的 Xcode,这是一个老问题。原来这个问题是 Xcode 中的一个 bug,已经修复。

原创

我有一个通过制作新标签 iPhone 应用程序(使用 ARC)生成的故事板

在我的一个选项卡中,如果我将手势识别器(任何,但我们说 Pan)拖到控件上,然后将选择器设置为一个操作,它就会在我转到选项卡时立即崩溃。

控制台中没有任何内容——它似乎在加载情节提要时发生(从未调用 viewDidLoad)。

  1. 我不知道如何获取更多信息
  2. 在不同的选项卡上,这工作正常。这两个标签都是自动生成的。

(可能我在视图中搞砸了一些东西,但我不知道我做了什么)。

如果我以编程方式制作手势,它们可以正常工作,但让它在情节提要中工作很好,而且我担心任何错误都会在某些时候以其他方式导致崩溃。

更多信息

在模拟器中我得到了

-[__NSCFString setView:]: unrecognized selector sent to instance 0x6d2db70

再次,需要调试技术——例如,有没有办法找出对象 0x6d2db70 是什么?

这与这个问题完全一样(没有答案):

Gesture recognizer in Interface builder crashes my app

更多信息

这很容易重现

  1. 新的 iPhone 选项卡式应用程序、ARC 和 Storyboard 开启
  2. 将点击手势拖到第二个选项卡的视图上(适用于第一个)
  3. 创建一个 (IBAction)
  4. 将手势的选择器连接连接到 #3 中的操作
  5. 运行,转到第二个选项卡

崩溃。我的应用也一样,默认选项卡有效,其他选项卡无效

【问题讨论】:

  • 什么样的崩溃?信号? EXC_BAD_ACCESS?堆栈跟踪是什么?
  • 就是这样——控制台什么都没有。堆栈跟踪回到释放池中的 main (所以感觉就像内存损坏)。需要获得更多信息的想法。
  • 我做了很多 iPhone 调试,但对 4.2、ARC 等都是新手。我想要新技术的想法(我知道僵尸、调试 malloc 等——但他们不知道)似乎合适)。
  • 指向 main 的堆栈跟踪通常表明抛出了异常。是否设置了异常断点?
  • 除了设置识别器的目标和动作之外,它至少需要在一个视图的gestureRecognizers出口集合中。您可以通过将识别器放在视图上来做到这一点。但如果它不在任何gestureRecognizers 集合中,它应该是无害的。

标签: iphone objective-c ios interface-builder xcode-storyboard


【解决方案1】:

错误信息告诉我们程序正在向__NSCFString的一个实例发送setView:消息(这显然是NSString的私有实现类)。

确保您已尝试在启用僵尸的情况下运行。僵尸很容易导致无法识别的选择器错误。

如果它不是僵尸,则在-[NSObject doesNotRecognizeSelector:] 上放置一个断点。当断点被命中时,您也许可以仅从堆栈跟踪中找出问题所在。如果没有,您可以打印对象的debugDescription(与大多数类的description 相同)。

在模拟器上,你可以让调试器像这样打印对象的debugDescription

(gdb) frame 0
#0  0x013bcbff in -[NSObject doesNotRecognizeSelector:] ()
(gdb) po ((int*)$ebp)[2]
this is my test string

在设备上,您可以这样做:

(gdb) frame 0
#0  0x344bca22 in -[NSObject doesNotRecognizeSelector:] ()
(gdb) po $r0
this is my test string

更新

根据您的重现步骤,这是 UIKit 中的一个错误。 File a bug report. 您可以通过在SecondViewController 上创建一个强大的插座并将其连接到手势识别器来解决该错误。 确保在viewDidUnload 中将出口设置为零。

更新

永远不要将你的出口设置为零——部分错误是 UIKit 没有保留——你需要保留你的引用以确保识别器没有被释放。

【讨论】:

  • 开启僵尸表示点击手势是僵尸。 -[UITapGestureRecognizer 保留]:消息发送到已释放实例 0x6b5ba80
  • 我刚刚注意到 UIImageView 没有 GestureRecognizers 集合——我有其他 UIImageView 的手势工作(在检查器中也有 IB 警告)。
  • gestureRecognizers 属性是UIView 的一部分,所以UIImageView 继承了它。它没有被标记为IBOutletCollection,因此只有在您将识别器放在视图上时它才会显示在 IB 中。
  • 需要在viewDidUnload中设置outlet为nil。否则它不会在内存警告时被释放。
  • 哇!我也遇到过这个问题,直到我查看了管理器中的设备日志并发现 dosNotRecognizeSelector 是由我设法找到此页面的滑动引起的。我有同样的问题,并且上面的修复工作(只需 ctrl+将滑动手势拖到后备视图控制器的头文件并使其成为强插座 - 问题已解决)。谢谢!
【解决方案2】:

在我的例子中,当通过在代码中拖放为手势识别器自动创建 IBOutlet 时,Xcode 正确地创建了具有“强”属性的属性,但它还在其中添加了“设置为 nil” viewDidUnload。删除“设置为零”为我解决了这个问题。

【讨论】:

  • 这是有道理的——在以标准方式手动添加到 IBOutlet 后,我​​遇到了同样的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多