1

I know this has been discussed previously, in this question for instance: In Objective-C why should I check if self = [super init] is not nil?

- (instancetype)init
{
    self = [super init];    // Is potentially nil

    if (self)
    {
        // Initialization code here…
    }

    return self;
}

I understand that self might be nil, but why does that matter? All answeres I've seen just say that self might be nil but do not explain why it matters. If you send a message to nil nothing will happen. You don't nil-check in any other code (except in some cases) so why do you need to do it in init?

Community
  • 1
  • 1
  • 3
    `You don't nil-check in any other code (except in some cases)` - this statement scares me for your future – Simon McLoughlin Apr 15 '14 at 10:04
  • 1
    @SimonMcLoughlin In Objective-C, one usually does not nil-check, except in `init...` methods. – The Paramagnetic Croissant Apr 15 '14 at 10:04
  • 1
    @user3477950 well one is an objective-c developer and one can think of many hundreds of cases where one checks for nil. Just because it won't crash (not in all cases), doesn't mean nil is an appropriate value to receive. Would it be appropriate to display "(null)" to an end user? most certainly not – Simon McLoughlin Apr 15 '14 at 10:15
  • 3
    In addition to @SimonMcLoughlin, main scenario I can think of is you wouldn't want to store nil in an NSArray or NSDictionary. – Tim Apr 15 '14 at 10:18
  • @SimonMcLoughlin if you have to nil-check data that you are stuffing into user output, then you are pretty much doomed and need to change design. – The Paramagnetic Croissant Apr 15 '14 at 11:20
  • @Jeff the same goes for your reasoning. – The Paramagnetic Croissant Apr 15 '14 at 11:21
  • @user3477950 that is a ridiculous comment to make. There are many reasons why a design can't force that. Third party data you have no control over? Bugs (Both yours and third party), a file getting deleted missing some / all of the data, database issues, I could go on. There is a very well known programming principal of "failing gracefully", just because objective-c doesn't crash all of the time on nil's, doesn't take care of this for you. Bare minimum would be replacing nil's with default data or messages to the user to explain the situation – Simon McLoughlin Apr 15 '14 at 11:34
  • 1
    @user3477950 Such comments and attitude lead to very poor code and UI design, expecting the world to always be perfect for you – Simon McLoughlin Apr 15 '14 at 11:35
  • @SimonMcLoughlin That's not the job of the presentation layer. – The Paramagnetic Croissant Apr 15 '14 at 12:40
  • @user3477950 yes / no. At a high level should the presentation layer know to not place nil into a label? yes of course. At a low level should the business logic not equally know to not put bogus entires into the database, that it knows will force the presentation layer to figure out a way to handle it, yes it should absolutely stop that from happening. Likewise with parsing data form servers or other sources, you should validate the data well before it hits the presentation layer. All integration points in / out of your control need to be validated – Simon McLoughlin Apr 15 '14 at 13:05
  • @user3477950 Otherwise your code is tightly coupled and when your business logic gets reused somewhere else, your forcing code duplication into the presentation layer or where ever else, opening up the risk to having the same bugs again and the increased work effort. Good, clean, reusable code should always nil check, no matter what layer its in – Simon McLoughlin Apr 15 '14 at 13:06

2 Answers2

1

If you send a message to nil nothing will happen.

That's correct, because the runtime (messenger function) checks for nil before actually calling the method.

However, if you set self to nil while it's in the middle of a method call, any direct instance variable access will trigger a null pointer dereference:

self.myVar = ...;  // fine
_myVar = ...;     // fine

self = nil;

self.myVar = ...;  // fine
_myVar = ...;     // wrong
  • @newacct The (wrong and radical) edit of Wain introduced the word "exception". I've hunted down the word in the beginning of the answer, but it looks like I haven't found the second instance. (I myself have never asserted that it's going to be an exception, not even a segfault, since it isn't -- dereferencing a null pointer has undefined behavior, which I know very well, unless someone bungles into my post...) – The Paramagnetic Croissant Apr 16 '14 at 05:47
  • I did not know this. I half didn't believe it until I tried it myself. Just a super-cool edge case. I say edge case since you can only assign `self` in an "method in the init family" and then you must forgo the `if(self)` check. You can really see the underlying struct-iness from the address that produces the `EXC_BAD_ACCESS`. Thanks for this answer. – NJones Apr 16 '14 at 14:16
  • @NJones: "since you can only assign self in an "method in the init family"" in ARC that is – user102008 Apr 16 '14 at 19:07
0

Partly convention, partly you're right, but it does depend on what you're going to setup using self.

In some cases you will be doing a lot of configuration, and creating all of that configuration when it won't actually be used is wasteful.

In some cases you may be passing nil to some configuration that will raise an exception when you do so, so checking and not making that call is sensible.

Following the convention is the safe and appropriate approach to take, and it really doesn't cost you anything (it's created for you by the template code).

Wain
  • 118,658
  • 15
  • 128
  • 151