0

I'm getting this error when I click my SKNode(SpriteKit Button): Thread 1:EXC_BREAKPOINT (code=EXC_ARM_BREAKPOINT, subcode=0xe7ffdefe)

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {

    for touch: AnyObject in touches {

        let location = touch.locationInNode(self)

        if playButton.containsPoint(location) {

            random()

        }
    }
}
Max Kortge
  • 527
  • 7
  • 23

1 Answers1

3

Breakpoints in Xcode

This exception probably doesn't indicate a breakpoint you set, but here's an overview for those who aren't familiar.

In Xcode, a breakpoint is an object that points to a line of code for debugging purposes. In the code editor, clicking a line number adds a breakpoint to that line. A breakpoint, typically blue, looks like a small arrow-like rectangle over a line number. When you run your program and that line of code gets executed, the program will crash and lldb (Apple's debugger) will give you information about the variables in that scope. This is useful for seeing what is stored in certain variables and for checking that a block of code is being executed at all. By performing a secondary (right) click on a breakpoint and selecting "Edit Breakpoint", a developer can choose advanced options like allowing execution a certain number of times before crashing.

When you click your button, the code in that block is being executed, a breakpoint is hit, and the program aborts. This is probably not a breakpoint you set, but an internal one.

To remove a breakpoint, perform a secondary (right) click and select "Remove Breakpoint". Alternatively, you can choose to disable it. This will fade it out.

You can see an overview of your breakpoints in the Breakpoint Navigator.

Internal Breakpoints

This particular breakpoint indicates ARM and therefore makes me think it is an internal one with the ARM processor. Internally, iOS may provide breakpoints even when you did not set them.

32-Bit vs. 64-Bit

My guess is that your random() function is somewhere generating a 64-bit integer that may cause older 32-bit devices to crash.

Vastly simplified, the difference between 32 and 64 bit devices is about memory. Internally, when you create a variable or constant of any kind you are storing something in the device's memory. 64-bit processors are capable of accessing more memory than 32-bit ones. Additionally, 64-bit applications contain 64-bit data types.

Many Swift data types explicitly define various versions of themselves that are different bit-sizes. For example, Swift integers come in Int8, Int16, Int32, and Int64, plus unsigned versions of the same. Using Int64 on devices containing 32-bit processors will attempt to store a 64-bit Integer in 32-bit memory locations. You should be careful about the unmarked Int type, which is effectively a typealias for the largest Int a device can hold. You will get errors if you try to cast an Int64 to an Int32. On 32-bit devices, since Int will be Int32, casting an Int64 to an Int will result in an error, since you are effectively converting an Int64 to an Int32.

On older devices, you may be somehow generating an Integer too large for 32-bit processors, and since on these older devices Int is really Int32, you get what would be a buffer overflow in objective-c, but Swift promotes it to a crash. The basic arithmetic operators do not allow these types to overflow by default.

The Apple A7 processor in the iPhone 5s and iPad Air was the first 64-bit chip for Apple's mobile devices. Older devices will not play well with 64-bit data types. Note that iPod touch 5th gen contains an A5 processor and is 32-bit only, whereas iPod 6th gen contains an A8 processor and is 64-bit.

In your random() function, you should check for any random number generating functions that may be returning an Int64 and then casting to an Int. You may also be trying to add two Int32s, which might overflow an Int. (But you could still store it in an Int64.)

In short, ensure you never have a possibility of generating a number that is larger than the number of bits the data type can store. Remember, you can use an Int64 on a 32-bit device, but you then need to make sure you don't try casting to Int, which will be Int32.

Refer to this similar StackOverflow question.

Community
  • 1
  • 1
Matthew Seaman
  • 7,952
  • 2
  • 37
  • 47
  • Thank you! This solves a lot of problems that I could come across in the future! – Max Kortge Jan 02 '16 at 07:08
  • I corrected some places that may have been misleading. `Int` is basically a typealias for the largest integer the device can store. It could be either bit size. The error is likely due to what would have been a buffer overflow (if Swift didn't prevent it) caused by somewhere generating a number that may be too large for a device. For example, adding to `Int32`s is nit safe on a 32-bit device. – Matthew Seaman Jan 09 '16 at 02:32
  • Also just corrected some explanation on the uses of Swift `Int` types and other causes of error. – Matthew Seaman Jan 18 '16 at 05:22