1

According to the class reference, the completion handler for captureStillImageAsynchronouslyFromConnection accepts a NSError object, but it is not an optional.

Function Declaration:

func captureStillImageAsynchronouslyFromConnection(connection: AVCaptureConnection!, completionHandler handler: ((CMSampleBuffer!, NSError!) -> Void)!)

Yet in the description for the parameters, it says nil may be returned in the completion handler in place of the NSError object if the request was fulfilled.

Parameters Description:

If the request could not be completed, an NSError object that describes the problem; otherwise nil.

The description suggests the declaration should contain an optional for the NSError object, doesn't it? Aren't the parameters description and function declaration conflicting?

Crashalot
  • 33,605
  • 61
  • 269
  • 439

1 Answers1

1

As long as you don't unwrap and use an optional that is null, you are fine.

Here is a sample code to show the variations. Note the callback signature is using implicit unwrapped optionals while the parameters passed can be nil.

import Foundation

struct Buffer {
}

func foo(callback: (buffer: Buffer!, error: NSError!) -> Void) {
    print("#1: buffer and error are nil")
    callback(buffer: nil, error: nil)
    print("#2: buffer not nil, error is nil")
    callback(buffer: Buffer(), error: nil)
    print("#3: buffer is nil, error is not nil")
    callback(buffer: nil, error: NSError(domain: "domain", code: 123, userInfo: nil))
    print("#4: both buffer and error are not nil")
    callback(buffer: Buffer(), error: NSError(domain: "domain", code: 123, userInfo: nil))
}

func cb(buffer: Buffer!, error: NSError!) {
    if let buffer = buffer {
        print(buffer)
    }
    else {
        print("buffer is nil")
    }

    if let error = error {
        print(error)
    }
    else {
        print("error is nil")
    }
}

foo(cb)

As seen from this example, an implicit unwrapped optional can be nil. That's what the description states for NSError.

John Difool
  • 5,572
  • 5
  • 45
  • 80
  • so the reason for using an implicit unwrapped optional in the declaration, as opposed to a normal optional, is that you're not forced to use ! throughout the function itself? thanks! – Crashalot Mar 21 '16 at 19:05
  • That's a great reason but be careful not to overdue it. There are some good use cases for it but safety wins. Please, check @drewag's post at this link: http://stackoverflow.com/questions/24006975/why-create-implicitly-unwrapped-optionals to get more insigh on the many ways to use it while playing safe. – John Difool Mar 21 '16 at 19:10
  • yup, understood. just trying to understand why apple used an implicit unwrapped optional as opposed to a normal optional. is that the reason? – Crashalot Mar 21 '16 at 19:24
  • This is a legacy API using the now vetust NSError parameter and soon to be replaced with Swift throw error handling. If everything was written in Swift, life would be simpler. You can read more about it under '2. Interacting with an Objective-C API' at the link I provided you in my last reply. – John Difool Mar 21 '16 at 19:41
  • vetust? ok thanks! makes more sense that it's a legacy issue. you're very helpful and responsive. – Crashalot Mar 21 '16 at 19:42
  • thanks, only wish it weren't so true hahaha. thanks again for being so helpful! – Crashalot Mar 21 '16 at 19:51