UITapGestureRecognizer 在多次点击时崩溃

Posted

技术标签:

【中文标题】UITapGestureRecognizer 在多次点击时崩溃【英文标题】:UITapGestureRecognizer crashes on multiple taps 【发布时间】:2016-05-02 12:33:37 【问题描述】:

我正在以编程方式将UIImageView 添加到UIScrollView 中,并在imageView 上添加点击手势。它准确地识别了 4 次点击事件,并且在第四次崩溃时没有任何明确的错误消息。这是在名为 FeaturedListingDetailVC

的控制器中

代码:

let frame = CGRect(x: 0, y: 0, width: 128, height: 128)
_iv = UIImageView(frame: frame)
_iv.image = UIImage(named: "no_media")            
_iv.userInteractionEnabled = true

tapGesture = UITapGestureRecognizer(target: self, action: #selector(initImagePopup(_:)))
_iv.addGestureRecognizer(tapGesture)

_iv.widthAnchor.constraintEqualToConstant(CGFloat.init(128)).active = true
_iv.heightAnchor.constraintEqualToConstant(CGFloat.init(128)).active = true
hrScroll.addSubview(_iv)

点击时调用的函数:

@objc func initImagePopup(gesture: UITapGestureRecognizer) 
    print("I am tapped!!!")

此外,我加载目标视图控制器的方式(即 FeaturedListingDetailVC) 确实很重要,但我不知道为什么以及如何。因为当我将目标 viewController 推入 UINavigationViewController 时,它会在第一次点击时崩溃,否则当我通过演示视图控制器初始化目标 VC 时,它会在第四次点击时崩溃。

使用以下代码初始化时第一次点击崩溃:

let storyboard = UIStoryboard(name: "Post", bundle: nil)
let featuredVC = storyboard.instantiateViewControllerWithIdentifier("FeaturedListingDetailVC") as! FeaturedListingDetailVC
self.vc?.navigationController!.pushViewController(featuredVC, animated: true)

使用以下代码初始化时在第 4 次点击时崩溃:

let storyboard = UIStoryboard(name: "Post", bundle: nil)
let featuredVC = storyboard.instantiateViewControllerWithIdentifier("FeaturedListingDetailVC") as! FeaturedListingDetailVC
self.vc?.navigationController!.presentViewController(featuredVC, animated: true, completion: nil)

回溯:

* thread #1: tid = 0x78c3e, 0x0000000106365553 UIKit\`-[UIViewController(UIKitManual) release] + 122, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
    frame #0: 0x0000000106365553 UIKit\`-[UIViewController(UIKitManual) release] + 122
    frame #1: 0xfffffffee7368160
    frame #2: 0x0000000105bf72f3 UIKit\`-[UIViewController setChildModalViewController:] + 248
    frame #3: 0x0000000105be853e UIKit\`-[UIViewController dealloc] + 1329
    frame #4: 0x0000000105f48b31 UIKit\`_UIGestureRecognizerSendTargetActions + 162
    frame #5: 0x0000000105f4519a UIKit\`_UIGestureRecognizerSendActions + 162
    frame #6: 0x0000000105f43197 UIKit\`-[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 843
    frame #7: 0x0000000105f4b655 UIKit\`___UIGestureRecognizerUpdate_block_invoke898 + 79
    frame #8: 0x0000000105f4b4f3 UIKit\`_UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 342
    frame #9: 0x0000000105f38e75 UIKit\`_UIGestureRecognizerUpdate + 2634
    frame #10: 0x0000000105ac548e UIKit\`-[UIWindow _sendGesturesForEvent:] + 1137
    frame #11: 0x0000000105ac66c4 UIKit\`-[UIWindow sendEvent:] + 849
    frame #12: 0x0000000105a71dc6 UIKit\`-[UIApplication sendEvent:] + 263
    frame #13: 0x0000000105a4b553 UIKit\`_UIApplicationHandleEventQueue + 6660
    frame #14: 0x00000001046f2301 CoreFoundation\`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #15: 0x00000001046e822c CoreFoundation\`__CFRunLoopDoSources0 + 556
    frame #16: 0x00000001046e76e3 CoreFoundation\`__CFRunLoopRun + 867
    frame #17: 0x00000001046e70f8 CoreFoundation\`CFRunLoopRunSpecific + 488
    frame #18: 0x000000010bf6ead2 GraphicsServices\`GSEventRunModal + 161
    frame #19: 0x0000000105a50f09 UIKit\`UIApplicationMain + 171
  * frame #20: 0x0000000103e34b22 JaClassified\`main + 114 at AppDelegate.swift:5
    frame #21: 0x000000010886b92d libdyld.dylib\`start + 1
    frame #22: 0x000000010886b92d libdyld.dylib\`start + 1

【问题讨论】:

你试过调试吗? “崩溃”并不是一个很好的问题描述! 你能发布回溯吗? 确保在不再需要观察者时将其移除。它可能会崩溃,因为您正在向不再存在的对象发送事件。 它不显示任何回溯,仅在 AppDelegate 中显示以下错误:Thread 1: EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP, subcode=0x0) @simpleBob 除了打印语句,我没有执行任何操作。它应该识别多次。 【参考方案1】:

听起来很奇怪,我已经测试了很多你的代码,没有办法,总是崩溃。

所以我只是尝试更改回调方法的名称:

 func didTapOnImagePopup(recognizer: UITapGestureRecognizer) 

它有效。

我真的不知道为什么,我可以找到任何合理的解释。

我唯一能想到的是应该存在一个名为“initImagePopup”的内部函数......但这很奇怪。

我真的很好奇真正的解释,如果有人知道的话。

【讨论】:

啊!我永远无法想象这一点。它吃了我一整天。谢谢@Luca 我也没有.. 但了解原因会很有趣!

以上是关于UITapGestureRecognizer 在多次点击时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

使用 UITapGestureRecognizer 无法识别的选择器

UIlabel 中的 UITapGestureRecognizer 错误

UITapGestureRecognizer 的问题

带有点击事件的 UITapGestureRecognizer

UIButton 上的 UITapGestureRecognizer

为啥 UIButton 会覆盖 UITapGestureRecognizer?