Re: Do we really need "if((self = [super init]))" in Objective-C anymore?


Jack Brindle
 

If we are adding alloc into the discussion, it is very important to realize that the value returned from alloc may not be the same as the one returned from the ensuing init.
This is best illustrated in cluster classes (there are many, one example is NSString). They will almost always return a different object than the original alloc.

One need not check the return from the [super  init] if self is not used in the init. It is quite comment to have:
- (instancetype) init
{
return [super init];
}

It is very useful for init to return nil if something is not valid when the init is being executed. This has nothing to do with the malloc used in alloc, but rather perhaps some
resource that is needed (picture, internet connect, or many other things) is not available. At that point the object cannot perform its function, so it is best to return nil
so that the object gets released/deleted and the calling method handles things properly.

Thus it is still a very useful situation to check the value returned by init to make sure it is valid, and so that you don’t try to do the further initialization that has just become superfluous.

Or to put it another way, if I were reviewing code and the returned init value wasn’t checked, I would most likely write a comment pointing out things. But then we should
always do the proper error checking on all methods.
 
- Jack



On Aug 17, 2017, at 11:39 AM, Jens Alfke <jens@...> wrote:


On Aug 17, 2017, at 11:06 AM, dhoerl <dhoerl@...> wrote:

So really, if Swift expects Foundation to always return a real object, why not use the same construct in Objective C:

The Obj-C behavior is historical. Back in the day of NEXTstep it was a realistic expectation that the process could run out of heap space and malloc() would return NULL, meaning +alloc would return nil. So any call to +alloc had to expect this possible error condition. (Yes, even on a 68030 a process had about 2GB of available address space. But back when hard disks topped out at a few hundred MB, there was no way to allocate that much backing store; your disk would fill up first.)

Somewhere along the line, I think prior to 10.0 but I'm not sure, that changed — in the modern era, running out of address space is considered unlikely enough that malloc() never returns NULL, it aborts instead if it can't allocate. And both macOS and iOS try to keep things from reaching that state — macOS will start freezing apps if the disk fills up (I've seen this happen) and iOS of course kills your app if it goes over a few hundred MB.

These days, yeah, it's pretty safe to skip checking the result of [super init], unless of course that method declares a nullable return value. I still do it, though.

—Jens

Join xcode@apple-dev.groups.io to automatically receive all group messages.