Convincing Swift that a function will never return, due to a thrown Exception
Swift's @noreturn
attribute marks functions and methods as not returning to their caller.
As probably the simplest example, the signature of the built-in function abort()
's is:
@noreturn func abort()
This gives the compiler all the information it needs. For example, the following will compile just fine:
func alwaysFail() -> Int { abort()}
Although alwaysFail()
theoretically returns an Int
, Swift knows that execution can't continue after abort()
is called.
The reason my original code didn't work is because NSException.raise
is a pre-Swift method, and therefore doesn't have the @noreturn
attribute. To easily solve this, I can either use abort()
:
func shouldBeOverridden() -> ReturnType { println("Subclass has not implemented abstract method `shouldBeOverridden`!") abort()}
or, if I still want to use NSException
, I can define an extension with the proper attribute
extension NSException { @noreturn func noReturnRaise() { self.raise() abort() // This will never run, but Swift will complain that the function isn't really @noreturn if I don't call a @noreturn function before execution finishes. }}
As a third option, I can just use a never-called abort()
after an NSException.raise()
to placate the compiler. The earlier option, using an extension
, is really just an abstraction for doing this:
func shouldBeOverridden() -> ReturnType { let exception = NSException( name: "Not implemented!", reason: "A concrete subclass did not provide its own implementation of shouldBeOverridden()", userInfo: nil ) exception.raise() abort() // never called}
In Xcode 8 beta 6 (Swift 3 beta 6) you can now use the Never
return type instead of @noreturn
to indicate that a function won't return to its caller:
func crash() -> Never { fatalError("Oops")}
It sounds like what you're doing would be better accomplished by creating a protocol and making shouldBeOverridden
a required method, then having your classes conform to that protocol. https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html