Swift - Boundingbox Cause Exc_Bad_Access (Code=1)

How to solve SceneKit Renderer EXC_BAD_ACCESS (code=1, address=0xf000000010a10c10)?

It's my experience that those kind of errors occur when you attempt to modify SceneKit's scene graph (add/remove nodes, etc) outside the SCNSceneRendererDelegate delegate methods.

Imagine you have one thread that is performing rendering at 60fps, and another (eg; the main thread) that removes a node from what is to be rendered. At some point the rendering thread is going to be part way through rendering when what it is rendering is removed by the other thread. This is when the EXC_BAD_ACCESS occurs. The more times the scene is modified, the more likely you are to see this conflict, hence why button mashing could more readily reproduce the issue.

The fix is to only modify your scene in one of SCNSceneRendererDelegate delegate methods. I'd try something like...

func cycleCarNext() {
self.cycleNextCar = true
}

func renderer(renderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
if (self.cycleNextCar) {
self.doCycleNextCar()
self.cycleNextCar = false
}
}

func doCycleNextCar() {
var indexOfCurrentCar = 0
for (index, car) in UserData.shared.unlockedCars.enumerated() {
if car.type == self.overlayScene.currentCarOnDisplay {
indexOfCurrentCar = index
break
}
}

if indexOfCurrentCar < UserData.shared.unlockedCars.count - 1 {
let nextCar = UserData.shared.unlockedCars[indexOfCurrentCar+1]
self.playerNode.removeFromParentNode()
self.playerNode = nextCar
self.playerNode.name = "player"
self.playerNode.position = SCNVector3(x: 17, y: 0.3, z: 0)
self.playerNode.eulerAngles = SCNVector3(x: 0, y: toRadians(angle: 45),z: 0)
self.scene.rootNode.addChildNode(self.playerNode)
self.overlayScene.currentCarOnDisplay = nextCar.type
self.overlayScene.updateGarageInterface()
} else {
guard let nextCar = UserData.shared.unlockedCars.first else { return }
self.playerNode.removeFromParentNode()
self.playerNode = nextCar
self.playerNode.name = "player"
self.playerNode.position = SCNVector3(x: 17, y: 0.3, z: 0)
self.playerNode.eulerAngles = SCNVector3(x: 0, y: toRadians(angle: 45),z: 0)
self.scene.rootNode.addChildNode(self.playerNode)
self.overlayScene.currentCarOnDisplay = nextCar.type
self.overlayScene.updateGarageInterface()
}
}

cycleCarNext is to be called by your main thread as it currently is. You'll likely need to set the SCNView's delegate somewhere too (eg; sceneView.delegate = self)

The idea is that while the cycleCarNext boolean is set immediately in the main thread, the scene isn't changed. Instead the change occurs at the correct time/thread in the SceneKit rendering loop.

UICollectionView Crashes with Error : Thread 1: EXC_BAD_ACCESS

As @rmaddy and @Prashant pointed out,

You should not use cellForItemAt in sizeForItemAT because
sizeForItemAt is called BEFORE initializing the cell in
cellForItemAt

And most probably that's the reason for your crash. Coming towards Solution.

I was faced with a similar problem (had to dynamically manage height) and what i did is something like

Calculate the estimated width of your label based on text. use the following string extension

//calculates the required width of label based on text. needs height and font of label
extension String {

func width(withConstrainedHeight height: CGFloat, font: UIFont) -> CGFloat {

let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil)

return ceil(boundingBox.width)
}
}

Now, inside sizeForItemAt

    //put actual lblHeight here
let lblHeight = Put_actual_label_height_here // e.g 30

//put actual label font here
let lblFont = Put_actual_label_font_here //e.g UIFont.boldSystemFont(ofSize: 20)

//calculate required label width
let lblRequiredWidth = yourLabel's_Text_String.width(withConstrainedHeight: lblHeight, font: lblFont)

//you may want to return size now
let height = yourItemsHeight
return CGSize(width: lblRequiredWidth, height: height)

Now that you have got the required width of your label, you can adjust the size of the item based on label's width.

Hope that helps. Let me know if you need any help. Thanks

The Vision API in Xcode 10/Swift doesn't detect anything. Am I doing something obviously wrong?

fileprivate var lastObservation: VNDetectedObjectObservation? 

This property is Optional, so starts as nil.

Every call of captureOutput didOutput will check if its nil and exit. so it will never be set. Remove let observation = lastObservation from your guard statement and this will fix your initial issue. You may then need to change the logic slightly



Related Topics



Leave a reply



Submit