For example, say you've implemented your own ordered-set class,
MyOrderedSet. Obviously it will have an interface similar to both the
NSSetclass and the
NSArrayclass in Cocoa's Foundation framework. As part of making it work like the Foundation collections, you'll probably want to do things like make it throw an
NSRangeExceptionif the caller requests the object at an index that's at or beyond the collection's
You might be tempted to implement this using a form of assertion, since by default assertions in Cocoa will throw an exception. But remember, this is part of the API contract of your class, not just an internal detail that should never go wrong! Thus if you do implement this using an assertion, and you disable assertions in your Release build, your Release build will wind up implementing your API incorrectly.
The solution is to distinguish in your code between assertions that verify state that should never be incorrect, and checks that ensure preconditions that are specified as part of an API contract are valid. In the example above, you could easily use a check to cause a range exception to be thrown, and this would still be compiled into your Release build.
The Foundation framework in Cocoa doesn't have any pre-defined checks, but they're not hard to develop on your own, especially with C99 variadic macros. You'll probably want to use a syntax similar assertions in creating your check macro, for example,
MyCheck(condition, exceptionName, format, ...)and you'll probably want it to just throw the named exception with the given reason. If you take the time to make your checks easy to use, you'll definitely use them more, and if you make them use exceptions, you'll make it easy to ensure your application's state is rolled back in a sane fashion.
The behavior of your checks can even be specified as part of your unit tests. (It's 2007, you are writing unit tests, right?) You can write tests that mimic the misuses of your API that your checks are designed to trap, and then note that these misuses cause the appropriate exception to be thrown via OCUnit's