This page describes the Objective-C mapping for exceptions.
On this page:
Exception Inheritance Hierarchy in Objective-C
Here again is a fragment of the Slice definition for our world time server:
These exception definitions map as follows:
Each Slice exception is mapped to an Objective-C class. For each exception member, the corresponding class contains a private instance variable and a property. (Obviously, because
BadZoneName do not have members, the generated classes for these exceptions also do not have members.)
The inheritance structure of the Slice exceptions is preserved for the generated classes, so
EXBadZoneName inherit from
EXGenericError derives from
ICEUserException itself derives from
ICEException, which derives from
NSException. Similarly, run-time exceptions derive from a common base class
ICELocalException that derives from
ICEException, so we have the inheritance structure shown below:
Inheritance structure for exceptions.
ICEException provides a single method,
ice_id, that returns the Slice type ID of the exception. For example, the return value of
ice_id for our Slice
GenericError in module
Mapping for Exception Data Members in Objective-C
As we mentioned earlier, each data member of a Slice exception generates a corresponding Objective-C property. Here is an example that extends our
GenericError with yet another exception:
The generated properties for these exceptions are as follows:
This is exactly the same mapping as for structure members, with one difference: the
reason members map to
reason_ properties, whereas — as for structures —
errorCode maps to
errorCode. The trailing underscore for
name_ prevents a name collision with the
reason methods that are defined by
NSException: if you call the
name method, you receive the name that is stored by
NSException; if you call the
name_ method, you receive the value of the
name_ instance variable of
The same escape mechanism applies if you define exception data members named
Objective-C Mapping for User Exceptions
Initialization of exceptions follows the same pattern as for structures: each exception (apart from the inherited no-argument
init method) provides an
init method that accepts one argument for each data member of the exception, and two convenience constructors. For example, the generated methods for our
EXGenericError exception look as follows:
If a user exception has no data members (and its base exceptions do not have data members either), only the inherited
init method and the no-argument convenience constructor are generated.
init method and the no-argument convenience constructor initialize the instance variables of the exception with zero-filled memory, with the following exceptions:
- A string data member is initialized to an empty string
- An enumerator data member is initialized to the first enumerator
- A structure data member is initialized to a default-constructed value
If you declare default values in your Slice definition, the inherited
init method and the no-argument convenience constructor initialize each data member with its declared value instead.
If an exception has a base exception with data members, its
init method and convenience constructor accept one argument for each Slice data member, in base-to-derived order. For example, here are the methods for the
FileError exception we defined above:
init and the second convenience constructor accept three arguments; the first initializes the
EXGenericError base, and the remaining two initialize the instance variables of
Objective-C Mapping for Run-Time Exceptions
The Ice run time throws run-time exceptions for a number of pre-defined error conditions. All run-time exceptions directly or indirectly derive from
ICELocalException which, in turn, derives from
ICEException. (See the above illustration for an example of an inheritance diagram.)
By catching exceptions at the appropriate point in the hierarchy, you can handle exceptions according to the category of error they indicate:
This is the root of the complete inheritance tree. Catching
NSExceptioncatches all exceptions, whether they relate to Ice or the Cocoa framework.
ICEExceptioncatches both user and run-time exceptions.
This is the root exception for all user exceptions. Catching
ICEUserExceptioncatches all user exceptions (but not run-time exceptions).
This is the root exception for all run-time exceptions. Catching
ICELocalExceptioncatches all run-time exceptions (but not user exceptions).
This is the base exception for both operation-invocation and connection-establishment timeouts.
This exception is raised when the initial attempt to establish a connection to a server times out.
For example, an
ICEConnectTimeoutException can be handled as
You will probably have little need to catch run-time exceptions as their most-derived type and instead catch them as
ICELocalException; the fine-grained error handling offered by the remainder of the hierarchy is of interest mainly in the implementation of the Ice run time. Exceptions to this rule are the exceptions related to facet and object life cycles, which you may want to catch explicitly. These exceptions are
Creating and Initializing Run-Time Exceptions in Objective-C
ICELocalException provides two properties that return the file name and line number at which an exception was raised:
init method and the convenience constructor accept the file name and line number as arguments.
Concrete run-time exceptions that derived from
ICEException provide a corresponding
init method and convenience constructor. For example, here is the Slice definition of
The Objective-C mapping for
In other words, as for user exceptions, run-time exceptions provide
init methods and convenience constructors that accept arguments in base-to-derived order. This means that all run-time exceptions require a file name and line number when they are instantiated. For example, you can throw an
ICEObjectNotExistException as follows:
If you throw this exception in the context of an executing operation on the server side, the
operation instance variables are automatically initialized by the Ice run time.
When you instantiate a run-time exception, the base
NSException is initialized such that its
name method returns the same string as
userInfo methods return
Copying and Deallocating Exceptions in Objective-C
User exceptions and run-time exceptions implement the
NSCopying protocol, so you can copy them. The semantics are the same as for structures.
Similarly, like structures, when not using ARC, exceptions implement a
dealloc method that takes care of deallocating the instance variables when an exception is released.
Exception Comparison and Hashing in Objective-C
Exceptions do not override
hash, so these methods have the behavior inherited from
- User Exceptions
- Run-Time Exceptions
- Objective-C Mapping for Modules
- Objective-C Mapping for Identifiers
- Objective-C Mapping for Built-In Types
- Objective-C Mapping for Enumerations
- Objective-C Mapping for Structures
- Objective-C Mapping for Sequences
- Objective-C Mapping for Dictionaries
- Objective-C Mapping for Constants
- Objective-C Mapping for Interfaces
- Object Life Cycle