73

Most of the examples I found on the net write this:

if(x != nil)
    // ...

Is there any problems with this?

if(x)
    // ...

I tried both in a simple program and couldn't found any difference.

Cœur
  • 37,241
  • 25
  • 195
  • 267
kizzx2
  • 18,775
  • 14
  • 76
  • 83

4 Answers4

127

In Objective-C, nil is defined as a value called __DARWIN_NULL, which essentially evaluates to 0 or false in if-statements. Therefore, writing if (x == nil) is the same as writing if (!x) and writing if (x != nil) is equal to if (x) (since comparing to false creates a negation, and comparing to true keeps the condition the same).


You can write your code either way, and it really depends on which you think is more readable. I find if (x) to make more sense, but it depends on your style.

It's like comparing if (someCondition == true) versus if (someCondition).
It all depends on you, and who's going to be reading the code.


Edit: As Yuji correctly mentions, since Objective-C is a superset of C, any condition that evaluates to a value other than 0 is considered to be true, and therefore, if someCondition in the example above were to evaluate to an integer value of, say, -1, comparing it to true would result in false, and the if-statement would not be evaluated. Something to be aware of.

Itai Ferber
  • 28,308
  • 5
  • 77
  • 83
  • 12
    I should add that `if(someCondition==true)` is discouraged, because in C-derived languages, any value other than 0 can be in principle regarded as a Boolean true value, but due to historical reasons if `someCondition` is `-1` and `true` is defined as `1` then `someCondition==true` evaluates to false. – Yuji May 30 '11 at 15:05
  • @Yuji, that is correct. I was trying to imply though, that `someCondition` evaluates to a boolean, but that is an important warning. – Itai Ferber May 30 '11 at 15:13
  • 1
    Check the section "working with nil" in the Apple docs: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithObjects/WorkingwithObjects.html#//apple_ref/doc/uid/TP40011210-CH4-SW22 . As they say, both forms are fine. However, beware that there subtle and treacherous issues if you try to *cast* an Obj-C reference to BOOL, as described in http://www.mikeash.com/pyblog/friday-qa-2012-12-14-objective-c-pitfalls.html – algal Feb 20 '13 at 22:12
  • 1
    so if x==0; would if(x) and if(x!=nil) behave the same? – erik Jul 30 '14 at 14:55
  • @erik Yes, they should. `nil` is essentially equal to 0, so those conditions evaluate to to `if (0)` and `if (0 != 0)`, both of which are false. – Itai Ferber Jul 30 '14 at 21:08
  • @erik However, you should probably not be comparing an integer to `nil` (those are disparate types, and even if the compiler allows you to do that, it's just not semantically correct). `if (x)` and `if (x == 0)` are both more correct in that context (though you should probably just stick to `if (x)`). – Itai Ferber Jul 30 '14 at 21:09
  • I ran into an issue where an entity's property compared to nil was not behaving correctly. In my condition, i checked if (entityItem != nil) [array addObject:entityItem]. This was crashing with the complaint of inserting a nil object. In my debug console, if I typed entityItem != nil, it printed . If I po'd just entityItem, it printed nil. any ideas? – kevinl Aug 22 '16 at 22:01
  • @kevinl I'm assuming that `mutableArray` should be changed to `eventItemIds`, correct? What happens if you change the code to read `NSString *name = event.name; if (name) { [eventItemIds addObject:name]; }`? – Itai Ferber Aug 23 '16 at 20:19
  • @ItaiFerber correct. If I use the above logic, something insane happens. it enters the condition but then crashes saying I can't insert a nil object. I don't know if it's some threading issue, but I've never seen this before. – kevinl Aug 23 '16 at 21:37
  • @kevinl Hmm. Yeah, that's strange. What is the threading model of your application? Where is this code running? (On which thread/queue?) Do you have other threads/queues operating, and what are they doing? (Considering you have a `backgroundManagedObjectContext`, I assume there must be more than one thread/queue doing work here...) – Itai Ferber Aug 23 '16 at 21:48
  • @kevinl Additionally, is this happening for the very first event you look at in the loop, or some arbitrary one? Is there a pattern to where this is failing? Does it ever succeed? – Itai Ferber Aug 23 '16 at 21:49
  • It definitely seems like a race condition. It's happening once every 10-20 launches from the background. The code is running on the background thread. – kevinl Aug 24 '16 at 19:59
  • @kevinl Yeah — looks like you've hit upon the issue, though; without substantial additional information, I won't be of much help. Depending on your access to Xcode 8, I'd recommend trying to run it with [TSAN](http://clang.llvm.org/docs/ThreadSanitizer.html); it will likely be able to work out where the race condition is. – Itai Ferber Aug 24 '16 at 23:32
8

Both

if (x != nil)

and

if ( x )

are equivalent, so pick the variant that in your opinion makes your code more readable for you (and others who will read and support your code)

Vladimir
  • 170,431
  • 36
  • 387
  • 313
0

Both are the same and this is a style question and it boils down to whether you prefer:

  1. if (something) { ... }

    versus

  2. if (something != nothing) { ... }

I have always found #1 more clear but #2 is used extensively in documentation and hence the field so it is better to both know both forms and adapt to what a project uses and be stylistically consistent.

-2

The best and safe way to check nil is
Make a common method, and add all these null :

+ (NSString *)trimWhiteSpaceAndNewLine:(NSString *)string {
    NSString *stringSource = [NSString stringWithFormat:@"%@",string];
    if ([stringSource isEqualToString:@"(null)"]) {
        stringSource = @"";
        return stringSource;
    }
    if ([stringSource isEqualToString:@"<null>"]) {
        stringSource = @"";
        return stringSource;
    }
    if ([stringSource isEqualToString:@"<nil>"]) {
        stringSource = @"";
        return stringSource;
    }
    if ([stringSource isKindOfClass:[NSNull class]]) {
        stringSource = @"";
        return stringSource;
    }
    if ([stringSource isEqualToString:@""]) {
        stringSource = @"";
        return stringSource;
    }
    if (stringSource == nil) {
        stringSource = @"";
        return stringSource;
    }
    NSString *stringFinal = [stringSource stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    return stringFinal;
}  

And check

NSString *strUuid = [Common trimWhiteSpaceAndNewLine:[dict valueForKeyPath:@"detail.uuid"]];
        if (![strUuid isEqualToString:@""]) {
            // do your stuff
        }
Mihir Oza
  • 2,768
  • 3
  • 35
  • 61