开发者

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

开发者 https://www.devze.com 2023-03-17 09:35 出处:网络
This is considered typical - (id)init { self = [super init]; if (self) { // <#initializations#> } return self;

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 a开发者_开发百科nd shouldn't you handle that in the init method?"


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.


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号