How to check if object is nil? [duplicate] - ios

I am currently studying objective-c and the basic c programming language.
I have a questions about a particular line of code:
if (!balance)
Balance is an object that is created. I understand that this code is checking to see if the object balance is nil or not, is this correct?
Could somebody please explain how exactly the code checks for nil? Does it return 0 if the value of balance is nonzero and 1 if the value is 0?
Thanks in advance.

In Objective-C, nil is roughly analogous to 0, NULL or false, but for object pointers. In an if statement, it will behave the same as one of the aforementioned scalar values. For example, the following two if statements should produce the same results:
NSNumber *balance = nil;
if (!balance) {
// do something if balance is nil
}
if (balance == nil) {
// do something if balance is nil
}

NSLog should return (null) (which probably is description for nil), not NULL in console. Your check should look like this:
if (!controller)
{
// do some stuff here
}

If balance is nil then it will be a pointer to 0x0. That address is never used for a valid object.
In C anything within an if that evaluates to zero is considered a negative response, anything that evaluates to non-zero is a positive response.
Pointers evaluate to their address — exactly as if you cast them to an integral type. The ! means "NOT".
So the test is if(address of balance is not zero).

First you need to understand how if works. Basically, any non-zero value is treated as true and a zero value is treated as false.
Something as simple as if (10) will be treated as true while if (0) is treated as false.
Any expression evaluates to either a value of zero or a non-zero value.
An object pointer is just a number - a memory address. A nil pointer is simply an address of 0. Any non-nil pointer will have a non-zero address.
The ! operator negates that state. A non-zero value will be treated as a zero value and visa-versa.
So now combine all of this.
Foo *bar = nil;
if (bar) // false since bar is nil (or zero)
Foo *bar = [[Foo alloc] init]; // some non-nil value
if (bar) // true since bar is non-zero
Foo *bar = nil;
if (!bar) // true since !bar mean "not bar" which is "not zero" which is "non-zero"
Foo *bar = [[Foo alloc] init]; // some non-nil value
if (!bar) // false since !bar mean "not bar" which is "not non-zero" which is "zero"

Related

BOOL is returning YES for value 0 in objective-c?

I have Invisible = 0 in my model and I am trying get this in BOOL using this line.
BOOL invisible = [self.model objectForKey:#"Invisible"];
but invisible is YES instead of NO. I've also tried with bool but it is also true. I checked class of the object using [[self.model objectForKey:#"Invisible"] class] and it is showing _NSCFBoolean. What's wrong here? model is NSDictionary.
UPDATE
Okay so I found the real issue. I have Filter class where I have getter isInvisible and code is
- (BOOL)isInvisible {
return [[self.model objectForKey:#"Invisible"] boolValue];
}
When I call this first time it returns me NO. Which is good. Now immediately after that I call it again and it returns <nil>. Strange.
(lldb) po filter.isInvisible
NO
(lldb) po filter.isInvisible
<nil>
There is only 1 second difference between two po commands.
= [self.model objectForKey:#"Invisible"];
This will return an NSNumber object. If you want a BOOL primitive you can get it via the boolValue method so
= [[self.model objectForKey:#"Invisible"] boolValue];
Since you return BOOL value from isInvisible method, I believe nil is equivalent to 0. So 0 is equivalent to NO or false. hence filter.isInvisible should be NO or false.
Please just verify that in if statement in your code.
Example:
if (filter.isInvisible == NO){//Should be reached here}

How to check if view has tag?

Help me pls with this unexpected trouble.
if (view.tag != nil)
^^ this worked for me, but suddenly i've assigned 0 tag to the view, and now everything's broken.
How can i check if view has a tag assigned ?
Thanks
All views have a tag. default is Zero 0
It depend on what you have. I believe you should consider a view with tag 0 is a view that is not tagged. and start tagging from 1.
Since the tag property of a view is of type NSInteger it can not be nil. NSInteger is a primitive type and therefore can not have a nil pointer. The default value assigned to the property will be 0.
Also, when you compare nil with 0 it gives a YES in objective-c. Thats what is breaking your logic.
if (view.tag != nil) equivalent to if (view.tag != 0)
tag is non-negative value. if you don't set tag of a view then it's default tag is 0. so, you have always a tag associate with a view.
in this regards, if you set tag>0 then you can check
if(tag>0){
//do something
}else{
//this is not your view
}
But you can't check
if (view.tag != nil)// because nil compares with object and if that object not found then return nil. if you compare with it nil value with an integer number it will also return 0. you will get a unexpected result.
There are a couple of things to understand:
Tag is an unsigned integer, which is a primitive type, and nil is used to test for an unassigned object type.
The compiler will consider nil to be 0 in this context, which is the reason it doesn't "fire".
Solution:
Assign tag > 0.
Test using if (view.tag > 0) { ... }.

Comparing two NSNumbers using isEqualToNumber method

While I compare two NSNumbers using isEqualToNumber, it is returning a false if both numbers are nil. Why a comparison of sort [nil isEqual:nil] always returns false while nil == nil returns true ?
It is the standard behaviour. You will get the same result from isEqueslToString: etc. It is better this way, because you could have for example weak references to unequal objects, which would become equal uppon deallocation.
You can use a condition like number1.intValue == number2.intValue in which case it would return YES for 2 nil objects. However, you will also get YES for nil.intValue == #0.intValue
[nil isEqual:nil] compares objects while nil == nil compares pointers.
Pointer to nil is always equal to pointer to nil. On the other hand object that does not exist is not equal to anything.

Property access results unused but NSLog works fine

I'm trying to display results in a text label, but I get different result than NSLog:
if( [elementName isEqualToString:#"CommunityID"])
{
self.recordResults = FALSE;
ResultLabel.text = #"CommunityID: %#", self.soapResults;
NSLog(#"CommunityID:%#",self.soapResults);
self.soapResults = nil;
}
NSlog correctly shows the text result, but the UILabel doesn't. The error shows:
"Property access result unused - getters should not be used for side effects"
I don't understand how NSlog gets the info just fine but the other doesn't? Any ideas?
You can't assign directly, You need to do with stringWithFormat property
ResultLabel.text = [NSString stringWithFormat:#"CommunityID: %#", self.soapResults];
Just so you know what was happening and what the compiler warning was about…
In C and Objective-C, a comma (,) that's not separating arguments in a function or method call is the comma operator. It is a compound expression. The left-hand sub-expression is evaluated but its result is discarded. Then, the right-hand sub-expression is evaluated and the overall compound expression takes its value.
In your case, the compound expression was just used as a statement and its result was not used. So, your statement:
ResultLabel.text = #"CommunityID: %#", self.soapResults;
was the equivalent of:
ResultLabel.text = #"CommunityID: %#";
self.soapResults;
The second of those statements calls a property getter and discards the resulting value. The compiler is warning you. Either you didn't mean to do that (as in this case) or you were invoking the getter because the getter has side effects that you wanted, which is a really bad idea.

Objective C - differentiate between nil and 'no value'

im building a chart view and I'm giving it a datasource to which it can ask for a Y value that corresponds to a given X index. In some cases, there is no Y value for a given X index. I can't send nil in this circumstance, as 0 may be a perfectly valid Y value. What is the best way in objective C to communicate that there is No Value at all?
It seems to me that you're sending the data between the model and the view using some sort of object, perhaps NSNumber, that's holding a value, and you are retrieving the value by sending it a message, and you know that if the object is nil, the message send will return 0.
That's correct. In this case, simply check if the object is nil, and proceed accordingly:
- (void)plotValue:(NSNumber *)number
{
if (number == nil) {
// no value
} else {
// Value may be 0, but you can now safely plot it.
}
}
Don't use primitives in your data source, instead use NSNumber. Then you can differentiate between nil and an NSNumber storing the value 0.
nil is not 0. They are different.
If you are using NSNumber, then nil is clearly disjoint from the set of NSNumber.
If you are using int, then you can't use nil.
If you don't want to use an object (NSNumber), you can return a negative number (if possible) or the maximum/minimum integer that is unlikely to be returned by the datasource.
I'm assuming you're talking about some scalar like an NSInteger or something. If literally any integer is valid for the Y value, then there is no way to do this. However, most likely there is some practical range, so you can just choose some value outside this range to be "special". For example, Cocoa has the value NSNotFound, which NSArray will return if you ask for the index of an object that is not in the array. It is defined as the largest possible NSInteger. You could reuse this yourself if your Y value will never be NSIntegerMax.
The other option, assuming you don't want to create a special type just for this, would be to have your method return both Y and whether or not Y was actually found. For example, some rough pseudocode:
- (NSInteger)yForX:(NSInteger)x wasFound:(BOOL *)found {
if (yWasFound) {
if (found)
*found = YES;
return y;
} else {
if (found)
*found = NO;
return 0;
}
}
You could use NSNumber, as some have suggested, but I find it a little awkward to deal in NSNumbers just to get nil.

Resources