2

I have some code

    captureSession = AVCaptureSession()
    captureSession!.sessionPreset = AVCaptureSessionPresetPhoto
    let backCamera = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) etc...

Of course, this correctly does not work on simulator. No problem.

If you do run it on a simulator, it correctly crashes right here

    captureSession!.sessionPreset = AVCaptureSessionPresetPhoto

like this

enter image description here

As a curiosity, how would you "catch" that crash?

If I try to "try" it in different ways,

    try captureSession!.sessionPreset = AVCaptureSessionPresetPhoto

I only get...

/Users/jpm/Desktop/development/-/classes/CameraPlane.swift:67:3: No calls to throwing functions occur within 'try' expression

How is it you wrap and catch that type of call?


Just BTW for anyone specifically dealing with this annoyance in the Camera,

func cameraBegin()
    {
    captureSession = AVCaptureSession()

    if ( AVCaptureDevice.devices().count == 0 )
        {
        print("Running on simulator.")
        return
        }
    ...
Fattie
  • 27,874
  • 70
  • 431
  • 719
  • What error do you get in the log? "Unexpectedly found nil"? – FelixSFD Nov 05 '16 at 15:20
  • it's a BAD_ACCESS as show in the image, thanks Felix – Fattie Nov 05 '16 at 15:27
  • Somewhat related: [swift can catch fatal error?](http://stackoverflow.com/questions/31335023/swift-can-catch-fatal-error) & [How do I catch “Index out of range” in Swift?](http://stackoverflow.com/q/37222811/2976878) – Hamish Nov 05 '16 at 15:48

2 Answers2

2

try can only be used when calling a function that throws. These functions are explicitly marked with throws.

If you want to unwrap an optional safely (which I guess is what you want to achieve), you can use guard.

var number: Int?
guard let unwrappedNumber = number else {
    return
}
print("number: \(unwrappedNumber)")
Graham
  • 7,431
  • 18
  • 59
  • 84
FelixSFD
  • 6,052
  • 10
  • 43
  • 117
2

Unfortunately, EXC_BAD_ACCESS means it's too late to catch anything because the program will be stopped.

You can only "catch" exceptions that are provided by the language / runtime you use. That would be error objects in swift (or OjbC methods with an NSError** parameter), obj-c Exceptions you could catch with @try/@catch blocks (but they disrupt memory management and shouldn't be used for runtime error handling) or C++ exceptions.

So far, swift / objc don't have the concept of a NullReferenceException for a number of reasons, but EXC_BAD_ACCESS also occur when accessing already freed / invalid memory, which was a common programming error before ObjC ARC and swift. So only guarding against accessing the "0" memory address wouldn't help in those situations. Any handling of this would have to deal with all three of the above mentioned error/exception handling mechanisms and potentially corrupt memory management (unlike Java / .NET, there is no garbage collector that cleans up all the objects left over after performing an unexpected non-local return).

So the handling of the "bad" memory access is not protected by anything and will result in an immediate crash with no reasonable way to recover. So the only thing you can do is to perform runtime checks if the operation you are about to do is valid and use the "bang" (!) operator with caution.

Martin Ullrich
  • 94,744
  • 25
  • 252
  • 217