Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why not throw an exception if [super init] returns nil?

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?"

like image 841
Dan Rosenstark Avatar asked Jul 04 '11 18:07

Dan Rosenstark


People also ask

When to throw an exception instead of returning null object?

If the empty situation is on much more probability, it should return nullObject so that ALL outer code can/should handle them explicitly. 2. If the empty situation is less probability, why not throw the exception so that final call function can handle it directly. I believe the correct answer depends on the code that is calling the method.

When should a method throw an exception in a contract?

When methods cannot fulfill their contracts, they should throw and exception. When a contract violation can, must, or should be handled by the consumer’s code, the method should throw a checked exception. Methods should never return null to represent contract failure.

Is it a good idea to return Null from a service?

Returning null there is a good idea because the client code can know that something errored out in your web service. In the case of the client, I think the way you have it is good. I don't think there is a reason to throw another exception (even though you aren't in the web service anymore).

Why would a delegate throw an exception in a function?

The delegate could throw an exception if that's what the outside could would like, or let the function return null (if the outside code will check for that), or possibly take some other action.


2 Answers

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.

like image 142
vikingosegundo Avatar answered Sep 27 '22 19:09

vikingosegundo


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.

like image 32
Myron Slaw Avatar answered Sep 27 '22 19:09

Myron Slaw