Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we all check for if(self) in init methods?

I've been doing it religiously for a couple of years now. Checking for the validity of self after calling [super init...] methods:

self = [super init];
if (self != nil) {
    // initialize
}
return self;

You can do this in a variety of ways, as this question nicely sums up, but that question is about syntax, mine is about the concept.

I recently got a question from a colleague who's learning Objective-C and he asked me "why should I test for the existence of self, isn't it obvious that it's there?" and my short answer was "err, yeah, well there's instances where it can fail, so that's why." But the long answer is that I really don't understand myself why we test for it everywhere, when the instances where it could fail are very rare. Apple's reference guide tells us about some specific cases, like when initializing with files or when dealing with singletons. But these sound like very rare exceptions to the rule that [super init]s should just work.

So my question to you is this: Why do we always test the validity of self? Are we just implementing it everywhere to catch that one exception where it occurs? Why not just skip the whole if (self) thing and initialize our object if the chances of it succeeding are 100% (or is that never the case)?

P.S. I realize this question must be a dupe since it's so basic, but my search queries got a lot of other questions about the syntax of initialization. Dupe links are appreciated, cheers!

like image 658
epologee Avatar asked Mar 15 '12 11:03

epologee


2 Answers

Here's a helpful old article on the subject, also including some common misconceptions about the initializer. I'd say the basic idea is that a particular class shouldn't have to be concerned with the implementation of its superclass, so we always check for nil in case of an error.

like image 187
jtbandes Avatar answered Nov 12 '22 06:11

jtbandes


uhm...this is definitely a good question, I wish I have made it. I am not an expert in objective-c, but I would try to give my opinion, without fear of downvoter :-)

I can feel your frustration but:

err, yeah, well there's instances where it can fail, so that's why.

It is a perfectly good answer. I think that you are not checking for self, but you are checking if the super object got initialized correctly, to me it is a different point of view.

I suppose in any case it is always good practice to check if the object has been allocated and initialized correctly, especially in objective-c which sit on top of C with all the masquerade memory allocation issues. Init come after 'alloc', and it is supposed to initialize the allocated object with variables etc...

For example, in languages like Java where the chain of constructors is well defined and checked by the compiler, failing to construct an object will result in a null pointer error at later use of that object. Often the allocation of object in Java is error free, but often using of methods has to surrounded by ad hoc try/catch error block. So the check is made later in the application lifecycle.

In objective-c instead you may have a nil object for many reasons, and if there's no application crash you could end sending message to an invalid object. I must be honest, when instantiating directly from a subclass of NSObject I don't know the utility of checking nil. But if I am extending a class in a framework, or a static lib provided by others, I would definitely feel safe with a check for object validity.

like image 32
Leonardo Avatar answered Nov 12 '22 06:11

Leonardo