Bug ID: FB7658482
After some fiddling in and tearing apart the the project I have managed to distill it (using the techniques you mentioned):
- Create a new MacOS App using Storyboard
- In the ViewController.swift file place the code below
- Run the app and in the view that appears click and drag. You should get the BAD_ACCESS error.
//
// ViewController.swift
//
import Cocoa
import simd
/* MARK: About the Bug
This project is a segment of a larger project we have for a simple game engine with metal.
There is a lot of matrix operations in the app so we utilize `didSet` heavily to update different
matrices.
In this example we have:
- Storyboard with NSView
- We add a pan gesture to capture the and convert it to rotation.
- We are a "Camera" class that has a rotation property that utilizes a didSet
This did set, in the real application, does some math for matrix updates which is not present here.
Reproducing the Bug
- Run the application and in the view that pops up just click and drag.
Ways the bug disappears:
A. Remove the 'didSet' from the camera rotation property.
B. Instead set the rotation property as a whole, rather than the individual components.
See the respective comments below for the code bits to uncomment/remove.
*/
class ViewController: NSViewController {
let camera:Camera = Camera()
override func viewDidLoad() {
super.viewDidLoad()
addGestureRecognizers(to: view)
}
func addGestureRecognizers(to view: NSView) {
let pan = NSPanGestureRecognizer(target: self, action: #selector(handlePan(gesture:)))
view.addGestureRecognizer(pan)
}
@objc func handlePan(gesture: NSPanGestureRecognizer) {
let translation = gesture.translation(in: gesture.view)
let delta = SIMD2<Float>(Float(translation.x),
Float(translation.y))
camera.rotate(delta: delta)
gesture.setTranslation(.zero, in: gesture.view)
}
}
class Camera {
var rotation: SIMD3<Float> = [0, 0, 0] {
// A. Remove this setter to remove the EXC_BAD_ACCESS
didSet {
_something()
}
}
func rotate(delta: SIMD2<Float>) {
print("rotate delta: \(delta)")
// B: Uncomment this, and comment the two lines under 'Bug Here' below
// rotation = [ rotation.x + delta.x, rotation.y + delta.y, rotation.z]
// Bug Here
rotation.y += delta.x
rotation.x += delta.y
}
func _something() {
print("_something()")
}
}