Swift:从单击到双击的切换处理程序会导致EXC_BAD_ACCESS异常

时间:2015-05-26 23:12:22

标签: ios swift sprite-kit

在下面的代码中,捕获单个点击工作正常。但是,双击可生成EXC_BAD_ACCESS异常。此代码位于GameScene.swift内。

override func didMoveToView(view: SKView) {
    // Handle taps
    let tapHandler = UITapGestureRecognizer(target: self, action:Selector("doTap:"))
    tapHandler.numberOfTapsRequired = 2
    view.addGestureRecognizer(tapHandler)
  }

func doTap(sender: UITapGestureRecognizer) {

  // If tapHandler.numberOfTapsRequired = 2, this function never executes due to the exception.
  // If tapHandler.numberOfTapsRequired = 1, this function executes without problem.

}



Thread 1: EXC_BAD_ACCESS (CODE=1, ADDRESS=0x10)

libobjc.A.dylib`objc_msgSend:
    0x198617bc0 <+0>:   cmp    x0, #0
    0x198617bc4 <+4>:   b.le   0x198617c30               ; <+112>
    0x198617bc8 <+8>:   ldr    x13, [x0]
    0x198617bcc <+12>:  and    x9, x13, #0x1fffffff8
->  0x198617bd0 <+16>:  ldp    x10, x11, [x9, #16]
    0x198617bd4 <+20>:  and    w12, w1, w11
    0x198617bd8 <+24>:  add    x12, x10, x12, lsl #4
    0x198617bdc <+28>:  ldp    x16, x17, [x12]
    0x198617be0 <+32>:  cmp    x16, x1
    0x198617be4 <+36>:  b.ne   0x198617bec               ; <+44>
    0x198617be8 <+40>:  br     x17
    0x198617bec <+44>:  cbz    x16, 0x198617d80          ; _objc_msgSend_uncached_impcache
    0x198617bf0 <+48>:  cmp    x12, x10
    0x198617bf4 <+52>:  b.eq   0x198617c00               ; <+64>
    0x198617bf8 <+56>:  ldp    x16, x17, [x12, #-16]!
    0x198617bfc <+60>:  b      0x198617be0               ; <+32>
    0x198617c00 <+64>:  add    x12, x12, w11, uxtw #4
    0x198617c04 <+68>:  ldp    x16, x17, [x12]
    0x198617c08 <+72>:  cmp    x16, x1
    0x198617c0c <+76>:  b.ne   0x198617c14               ; <+84>
    0x198617c10 <+80>:  br     x17
    0x198617c14 <+84>:  cbz    x16, 0x198617d80          ; _objc_msgSend_uncached_impcache
    0x198617c18 <+88>:  cmp    x12, x10
    0x198617c1c <+92>:  b.eq   0x198617c28               ; <+104>
    0x198617c20 <+96>:  ldp    x16, x17, [x12, #-16]!
    0x198617c24 <+100>: b      0x198617c08               ; <+72>
    0x198617c28 <+104>: mov    x2, x9
    0x198617c2c <+108>: b      0x198601e70               ; objc_msgSend_corrupt_cache_error
    0x198617c30 <+112>: b.eq   0x198617c48               ; <+136>
    0x198617c34 <+116>: adrp   x10, 17024
    0x198617c38 <+120>: add    x10, x10, #1904
    0x198617c3c <+124>: lsr    x11, x0, #60
    0x198617c40 <+128>: ldr    x9, [x10, x11, lsl #3]
    0x198617c44 <+132>: b      0x198617bd0               ; <+16>
    0x198617c48 <+136>: movz   x1, #0
    0x198617c4c <+140>: movi   d0, #0000000000000000
    0x198617c50 <+144>: movi   d1, #0000000000000000
    0x198617c54 <+148>: movi   d2, #0000000000000000
    0x198617c58 <+152>: movi   d3, #0000000000000000
    0x198617c5c <+156>: ret    

2 个答案:

答案 0 :(得分:1)

来自苹果文档:

  

虽然点击是离散手势,但它们对于每个状态都是离散的   手势识别器;因此,发送相关的动作消息   当手势开始时,为每个中间状态发送,直到   (包括)手势的结束状态。处理点击的代码   因此,手势应该测试手势的状态   例如:

func handleTap(sender: UITapGestureRecognizer) {
    if sender.state == .Ended {
        // handling code
    }
}

在操作完成之前调用doTap的概率正在崩溃应用程序。

我希望能帮助你。

答案 1 :(得分:0)

只有在点按两次时才会调用AFAIK func doTap(sender: UITapGestureRecognizer),因为您已将其设置为tapHandler.numberOfTapsRequired = 2条件。

您可以将println(sender.numberOfTapsRequired)放入func doTap进行测试。我相信,在编写代码时,它应始终= 2。

如果是这样,那么我相信你的if可能没有达到预期的效果,导致导致崩溃的其他后果。