Comparing NSNumber to 0 not working? - objective-c

I have a JSON parser in my app, and I load the value into a detailDataSourceDict variable. When I try to get the valueForKey of the array and try to compare it to 0, it never works...
Here's my code:
if (indexPath.row == 1) {
NSNumber *rating = [detailDataSourceDict valueForKey:#"rating"];
NSLog(#"Rating: %#",rating);
if (rating == 0) {
cell.detailTextLabel.text = #"This sheet has not yet been rated.";
}
else {
cell.detailTextLabel.text = [NSString stringWithFormat:#"This sheet has a %# star rating.",rating];
}
cell.textLabel.text = #"Rating";
}
I see in my JSON feed that "rating":"0", but when the rating is 0, it shows "This sheet has a 0 star rating.", instead of "This sheet has not yet been rated."
Any suggestions? Thanks.

NSNumber *rating is an object. 0 is a primitive type.
Primitive types can be compared with ==. Objects cannot; they need to be compared for equality using isEqual:.
Thus replace this:
rating == 0
with:
[rating isEqual:#0]
(#0 being a NSNumber literal)
or alternatively:
rating.integerValue == 0
The reason why your wrong code even compiles is that 0 is equal to 0x0 which in turn is equal to nil (kind of, sparing the details).
So, your current code would be equivalent to this:
rating == nil

rating is a pointer to an NSNumber object, if you compare with == 0, you'll be comparing the pointer only.
If you want to compare the value with 0, you'll have to get the actual value using intValue, try;
if ([rating intValue] == 0) {

NSNumber is an object and you have to access it's value with the value accessors.
[NSNumber intValue];
See "Accessing Numeric Values" #:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/Reference/Reference.html

You want to change it from:
if (rating == 0) {
To
if ([rating intValue] == 0) {

Related

Comparison between pointer and int (id to int) - Object wrapping still doesn't work [duplicate]

So my problem is this:
I am receiving a JSON string from across the network. When decoded (using SBJSON libraries), it becomes an NSDictionary that SHOULD contain a number of some sort for the key 'userid'. I say 'should' because when I compare the value to an int, or an NSINTEGER, or NSNumber, it never evaluates correctly.
Here is the comparison in code:
NSDictionary *userDictionary = [userInfo objectAtIndex:indexPath.row];
if ([userDictionary objectForKey:#"userid"] == -1) {
//Do stuff
}
The value inside the dictionary I am testing with is -1. When I print it out to console using NSLog it even shows it is -1. Yet when I compare it to -1 in the 'if' statement, it evaluates to false when it should be true. I've even tried comparing to [NSNumber numberWithInt: -1], and it still evaluates to false.
What am I doing wrong? Thanks in advance for your help!
You are comparing a pointer to an object, not an integer itself. You must first convert the object into an integer:
if ([[userDictionary objectForKey:#"userid"] integerValue] == -1)
{
//Do stuff
}

How do i compare string and integer?

i have basicly no knowledge of objective c, but how do i make a if statement to see if SourceTypeString is equal to 1 or 2?
NSString* sourceTypeString = [arguments objectAtIndex:2];
UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera; // default
NSLog(#"my ns string = %#",sourceTypeString);
//NEWBIE PART
if ((sourceTypeString == 1))
{
NSLog(#"equals 1");
sourceType = (UIImagePickerControllerSourceType)[sourceTypeString intValue];
} else {
NSLog(#"equals 2");
sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
//NEWBIE PART
My code crashes and gives me
my ns string = 1
(lldb)
sourceTypeString __NSCFNumber * 0x0013bf80 (int)1
if ([sourceTypeString intValue] == 1)
You can call intValue on an NSString to get its value as an int, if it is possible to do so with the given string. Then you can compare those.
You can't directly compare ints to strings. However, you can use NSString's isEqualToString to check if the first strings value is equal to the string value of the number.
if ([sourceTypeString isEqualToString:#"1"]) {
//
}

If and Else if Statement

Im wondering why this code won't work. It's for a calculator :)
I need the symbol (banana) to be recognised by the calculator and to use either +,- according to what the user inputs.
NSString *list = [Sum_TextField text];
NSArray *listItemsArray = [list componentsSeparatedByString:#" "];
int batman = [[listItemsArray objectAtIndex: 0] intValue];
NSString *banana = [listItemsArray objectAtIndex: 1];
int joker = [[listItemsArray objectAtIndex: 2] intValue];
{
Calculator* calc = [[Calculator alloc] init];
[calc setNum1:batman];
[calc setNum2:joker];
if ((banana = #"-"))
{
[calc minus];
}
else if ((banana = #"+"))
{
[calc add];
}
[Answer_TextField setText:[NSString stringWithFormat:#"%d", [calc answer]]];
}
}
To judge whether NSString is equal, you must use [#"AAAA" isEqualToString : #"BBBB"]. You can not use == , because they are not in the same address of the memory .
Here's how you want to do this:
if ([banana isEqualToString:#"-"])
{
[calc minus];
}
else if ([banana isEqualToString:#"+"])
{
[calc add];
}
= is assignment. It has absolutely nothing to do with comparison.
== is comparing the 2 expressions and see whether they are equal. This can be used to compare integral types (such as enum, char, int, short, long, long long, BOOL) or reference (check whether 2 pointers are pointing to the same object). Note that 2 pointers can point to 2 different object which contains the same value inside, but == will compare them as different. (Floating point type such as float and double requires a bit different method to compare equality).
As a method to preempt confusion between = and ==, for equality testing with ==, some people put the value on the left hand side, and the variable on the right hand side (e.g. 2 == variable). If they happen to mistype == to =, the compiler will complain.
If you want to compare the content of 2 objects, in this case is NSString, you should search for isEquals type of function. For NSString, you should use isEqualToString if you want to compare whether the 2 strings have the same content.

Null Detection in Xcode with sqlite

I'm writing some code here, and I'm having a had time.
I have a value in my Database that can be null as its an average of other data, if that data hasn't been populated there is nothing to take the average of.
In my query there will return a null value at times. The value that would be there normally is a double. SO i have
NSNumber *num = [NSNumber numberWithDouble:sqlite3_column_double(compiledStatement,7)];
if (num == nil) {
// do something
}
else {
// do something else
}
For some reason it is defualting to 0. When i NSLog it, it is 0, But using terminal, i'm able to be certain that my query (through terminal) is returning null for that value.
Any help would be greatly appreciated!
Thanks Guys!
By calling [NSNumber numberWithDouble:] you are guaranteeing that you get an NSNumber back. If you want to check for null, you have to do it separately, perhaps by calling sqlite3_column_type() and checking for SQLITE_NULL. Something like:
if ( sqlite3_column_type(compiledStatement, 7) != SQLITE_NULL )
{
NSNumber *num = [NSNumber numberWithDouble:sqlite3_column_double(compiledStatement,7)];
}

Converting NSNumber to NSString is not realy a string

I have got a problem with converting an NSNumber value to an NSString
MyPowerOnOrNot is an NSNumber witch can only return a 1 or 0
and myString is an NSString..
myString = [NSString stringWithFormat:#"%d", [myPowerOnOrNot stringValue]];
NSLog(#"%#",myString);
if(myString == #"1") {
[tablearrayPOWERSTATUS addObject:[NSString stringWithFormat:#"%#",#"ON"]];
}
else if(myString == #"0") {
[tablearrayPOWERSTATUS addObject:[NSString stringWithFormat:#"%#",#"OFF"]];
}
What is wrong with this?
The NSLog shows 0 or 1 in the console as a string but I can't check it if it is 1 or 0 in an if statement?
If doesn't jump into the statements when it actually should.. I really don't understand why this doesn't works..
Any help would be very nice!
A couple of problems
myString = [NSString stringWithFormat:#"%d", [myPowerOnOrNot stringValue]];
-stringValue sent to an NSNumber gives you a reference to a string. The format specifier %d is for the C int type. What would happen in this case is that myString would contain the address of the NSString returned by [myPowerOnOrNot stringValue]. Or, on 64 bit, it would return half of that address. You could actually use [myPowerOnOrNot stringValue] directly and avoid the relatively expensive -stringWithFormat:
if(myString == #"1")
myString and #"1" are not necessarily the same object. Your condition only checks that the references are identical. In general with Objective-C you should use -isEqual: for equality of objects, but as we know these are strings, you can use -isEqualToString:
if ([[myPowerOnOrNot stringValue] isEqualToString: #"1"])
Or even better, do a numeric comparison of your NSNumber converted to an int.
if ([myPowerOnOrNot intValue] == 1)
Finally if myPowerOnOrNot is not supposed to have any value other than 0 or 1, consider having a catchall else that asserts or throws an exception just in case myPowerOnOrNot accidentally gets set wrong by a bug.
"myString " is a reference to a string, not the value of the string itself.
The == operator will compare the reference to your string literal and so never return true.
Instead use
if( [myString isEqualToString:#"1"] )
This will compare the value of myString to "1"
In Objective C; you can't compare strings for equality using the == operator.
What you want to do here is as follows:
[tablearrayPOWERSTATUS addObject:([myPowerOnOrNot integerValue]?#"ON":#"OFF"])];
Compact, fast, delicious.