I've got an NSNumber whose value looks like this in the debugger:
(lldb) po avg
377.57142857142857142857142857142857142
When I ask it for its intValue, I get 377. Fine. But if I ask it for its longLongValue I get 0.
What gives?
Update: The full scenario is that I've got an array of NSNumber objects, and I'm getting its average like this:
NSMutableArray *myNums = nil; //assume this is full of numbers
NSNumber *avg = [myNums valueForKeyPath:#"#avg.self"];
int64_t result = avg.longLongValue; //this gets 0
I've stopped here in the debugger and I can p [avg longLongValue] and get 0. p [avg intValue] gets 377.
Update 2: Here is a reliable reproduction:
NSArray *testArr = #[#(392), #(392), #(339), #(394), #(393), #(394), #(339)];
NSNumber *testAvg = [testArr valueForKeyPath:#"#avg.self"];
int64_t testRes = testAvg.longLongValue;
NSLog(#"Result is %lli", testRes);
int res2 = testAvg.intValue;
NSLog(#"Int result is %i", res2);
The result log is:
Result is 0
Int result is 377
Your po [testAvg class] gives NSDecimalNumber which is the problem.
These links would explain why:
Link 1
Link 2
As link 1 suggested you should do [[testAvg stringValue] longLongVale]
Related
Imagine the following code:
NSMutableArray *arr = [NSMutableArray arrayWithObjects:#200, #100, nil];
NSInteger n1 = (NSInteger)[arr objectAtIndex:0];
NSInteger n2 = (NSInteger)[arr objectAtIndex:1];
NSInteger r = n1 + n2;
NSLog(#"n: %lid", r);
The result I am getting is: -4309586476825365866d, the expected one is: 300.
I also tried to evaluate the individual expressions in debugger to check what I am getting when reading the values from the array, like this: po (NSInteger)[arr objectAtIndex:0]. This showed the correct number, yet when trying to sum them both: po (NSInteger)[arr objectAtIndex:0] + (NSInteger)[arr objectAtIndex:0], an invalid result is generated.
Any ideas why? I am very new to Objective-C, so any source where I could get more info about the issue is appreciated.
You cannot cast NSNumber to NSInteger. You have to call integerValue.
And for more than 10 years there is a more convenient array literal syntax as well as a more convenient index subscription syntax
NSArray *arr = #[#200, #100];
NSInteger n1 = [arr[0] integerValue];
NSInteger n2 = [arr[1] integerValue];
NSInteger r = n1 + n2;
NSLog(#"n: %ld", r);
And for the string format use either i or d but not both.
Below is my Response
geolocation = {
loc = {
lat = "22.4409980000000004451976565178";
long = "70.0686230000000023210304789245";
};
};
My app crashes when I try below code:
NSNumber* n = [userPin valueForKeyPath:#"geolocation.loc.lat"];
NSLog(#"num is class %#", NSStringFromClass([n class]));
float fCost = [n floatValue];
When I print my NSStringFromClass I get __NSSingleObjectArrayI.
Any suggestion how to fix this?
At a guess the (runtime) type of userPin is array and it contains one element. When applied to an array valueForKey:, on which valueForKeyPath: is based, returns an array produced by applying itself to every element of the array.
If this is the case either index userPin before the call or handle the array resulting from the call.
Addendum
Could you give me an example?
Trivial example:
// An array of strings
NSArray *test = #[ #"The", #"quick", #"brown", #"fox"];
// Trivial keypath...
NSArray *result = [test valueForKeyPath:#"length"];
// Print
NSLog(#"%#", result);
Produces:
(
3,
5,
5,
3
)
showing result is an array of the result of applying length to each element of `test. HTH
I have this code:
NSObject *distanceInMeters;
distanceInMeters = [[[[[[googleMapsApiResult objectForKey:#"routes"] objectAtIndex:0] objectForKey:#"legs"] objectAtIndex:0] objectForKey:#"distance"] valueForKey:#"value"];
NSLog(#"%#", distanceInMeters); // this outputs 7578
NSDecimalNumber *roundTripInKilometers;
roundTripInKilometers = distanceInMeters / 500; // It says "Invalid operands to binary expression ('NSObject *' and 'int')
I expect to get 15.156 but it cannot divide object value with an integer. What should I do to get 15.156?
You can't divide number from NSObject, To do the same, You have to fetch the number from it and use it anywhere
NSNumber *distanceInMeters;
distanceInMeters = [[[[[[googleMapsApiResult objectForKey:#"routes"] objectAtIndex:0] objectForKey:#"legs"] objectAtIndex:0] objectForKey:#"distance"] valueForKey:#"value"];
NSLog(#"%#", distanceInMeters); // this outputs 7578
NSDecimalNumber *roundTripInKilometers = (NSDecimalNumber *)[NSDecimalNumber numberWithDouble:[distanceInMeters doubleValue] / 500.0];
There are many problems in your code. First, you need to convert the value you get from the API into an double. An easy way to do that would be to first convert it to an instance of NSString. Then get an double from the string with the method doubleValue.
Next divide that value by 500:
double roundTripInKilometersDouble = distanceInMeters / 500.0;
Then put that result into an NSDecimalNumber:
NSDecimalNumber *roundTripInKilometers = [NSDecimalNumber numberWithDouble: roundTripInKilometersDouble];
(Haven't tested this code.)
In CoreData I set type:
Integer 16
and inserted int like this:
[NSNumber numberWithInt:9]
and problem is when I get result from CoreData result is not 9, result is: 114726928
Does andbody know's why?
try the following:
NSInteger number = 9;
NSNumber *numberObject = [NSNumber numberWithInteger:number];
NSInteger numberFromNSNumber = [numberObject integerValue]; // it will contains the 9
it should be fine.
I'm trying to access an array using another array integer value as an index.
NSInteger index=[appDelegate.randomRiddles objectAtIndex:appDelegate.randomRiddlesCounter];
int i = index;
questionText.text = [[appDelegate.currentRiddlesContent objectAtIndex:i] objectForKey:#"question"];
//where appDelegate.randomRiddlesCounter is an NSInteger and appDelegate.randomRiddles is a NSMutableArray
However I'm getting incompatible pointer to int conversion warning. How can I fix this above code? The warning I get is coming from the first line.
Try:
NSNumber *index = [appDelegate.randomRiddles objectAtIndex: appDelegate.randomRiddlesCounter];
int i = [index intValue];
questionText.text = [[appDelegate.currentRiddlesContent objectAtIndex: i] objectForKey: #"question"];
NSInteger is an integral type, not an object.
Try this:
int i = [index intValue];
An NSArray like object can only store Objective-C object pointers (i.e. everything that you can assign to an id)
With objectAtIndex you get the object, with indexOfObject:(id)anObject you get the corresponding index.
These two instructions are both valid:
id bla = [appDelegate.randomRiddles objectAtIndex:appDelegate.randomRiddlesCounter];
NSInteger index = [appDelegate.randomRiddles indexOfObject:myObject];
The second assumes that myObject is at least of type id
So you try to convert a pointer to an int. Therefore the warning is issued.