Is if(obj && obj != nil) correct and necessary?
Two parts to this question
1) Is this understanding of what's going on correct?
"if (obj)" is testing to see if the pointer is not 0x0, aka set to an integer memory address "if (obj != nil)" is comparing the memory address of the object to the memory address of the univers开发者_JAVA技巧al nil object2) So in a situation where I don't know if a variable is pointing to anything, and if it is, I also don't know if that object is a valid object or nil. I want to do a variety of things based on that information, not just pass a message to obj, which I realize would be safe if it's nil. Is this code both correct and necessary?
if (obj && obj != nil) {
// Do a bunch of things that should only happen if obj is pointing to a valid object
[obj someMessage];
[anotherObj someOtherMessage];
}
Thanks guys!
Correct? Yes. Necessary? No. Objective-C simply #define
s nil
to (void *)0
, which is, in C terms, false. So simply writing
if (obj) {
[obj someMessage];
[anotherObj someOtherMessage];
}
is sufficient. Further, since Objective-C has message-eating nil
, you can simply omit the check in some circumstances. (E.g., if the second line were not there in the if
block, you could simply call [obj someMessage]
indiscriminately.)
This is correct, in the sense that it will give you the result you expect, but redundant. It's sufficient to just use:
if (obj) {
or
if (obj != nil) {
You can simply use if (obj)
. According to objc.h
, nil
is a #define
for __DARWIN_NULL
. Poking around in /usr/include/sys/_types.h
, we see that __DARWIN_NULL
is defined as 0L
, 0
, or (void *)0
, depending upon platform and whether you're using a C or C++ compiler. But in the end, nil
always evaluates to false, so the simpler if (obj)
will suffice.
Not a direct answer to your question, but to the question sort of implied by part 2: There is no way to tell whether a pointer references a "valid object" aside from sending a message and seeing if it does what you want. There are all kinds of things that aren't nil but still aren't what would be considered a "valid object" for most purposes. For example, an object variable might point to:
- The garbage space where a deallocated object used to live
- A new object that's been allocated in place of the object the variable is supposed to point to
- An int that you accidentally set the variable to
- A C string that you accidentally set the variable to instead of an NSString
There's no way to test at runtime if any of these are the case. You have to make sure your code is free of bugs that would put a variable into a state like that.
if (obj == nil) then if (obj) will evaluate false. You don't need both.
精彩评论