问题
This is considered typical
- (id)init {
self = [super init];
if (self) {
// <#initializations#>
}
return self;
}
but wouldn't it be better to go with something like this which actually responds appropriately?
- (id)init {
self = [super init];
if (self) {
// <#initializations#>
} else {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"you think your constructor is executing, but it's not"] userInfo:nil]
}
return self;
}
The corollary to this question is, "under what conditions would [super init]
return nil
and shouldn't you handle that in the init
method?"
回答1:
One reason, why you should do, what JustSid is saying:
In object-orientated design you should always code, as if you maybe will hand your class over to another project by another developer. So you can't assume, that a failure in initialization in his project may be as bad as it is probably in yours. Maybe this developer is you in 5 years. Imagine your hassle to fix your 200 classes, you want to reuse.
回答2:
No, exceptions in Objective-C are meant for states which you can't really recover from, not just something to show that an operation failed. If you initializer fails, simply return nil to show it.
回答3:
Not really.
with:
self = [super init];
you are calling your superclasses init method, which only in RARE cases will return nil. (like if the system has low memory, which you have other problems).
if(self)
this will not go through if no instance is returned (it is nil) so there is no need for the else.
the old way was
if((self = [super init))
{
// do initialization
}
return self
EDIT: Was reading the Cocoa Fundementals guide and found this under Error Handling:
If the error encountered in a method implementation is a system-‐level or Objective-‐C runtime error, create and raise an exception, if necessary, and handle it locally, if possible. In Cocoa, exceptions are typically reserved for programming or unexpected runtime errors such as out-‐of-‐bounds collection access, attempts to mutate immutable objects, sending an invalid message, and losing the connection to the window server. You usually take care of these errors with exceptions when an application is being created rather than at runtime. Cocoa predefines several exceptions that you can catch with an exception handler. For information on predefined exceptions and the procedure and API for raising and handling exceptions, see Exception Programming Topics.
For other sorts of errors, including expected runtime errors, return nil, NO, NULL, or some other type-‐suitable form of zero to the caller. Examples of these errors include the inability to read or write a file, a failure to initialize an object, the inability to establish a network connection, or a failure to locate an object in a collection. Use an NSError object if you feel it necessary to return supplemental information about the error to the sender. An NSError object encapsulates information about an error, including an error code (which can be specific to the Mach, POSIX, or OSStatus domains) and a dictionary of program-‐specific information. The negative value that is directly returned (nil, NO, and so on) should be the principal indicator of error; if you do communicate more specific error information, return an NSError object indirectly in a parameter of the method.
回答4:
Returning nil
is the appropriate thing to do. Part of the reason that sending any message to nil is allowed and defined to return nil as a result is that you can build compound statements like:
resultObject = [[[[class alloc] init] autorelease] someProperty];
That statement executes all the way through even if any individual method call returns nil. To fit with that, the init
convention is to return the nil if the superclass does so.
As JustSid points out, ObjC uses exceptions only for unrecoverable problems.
来源:https://stackoverflow.com/questions/6574938/why-not-throw-an-exception-if-super-init-returns-nil